diff --git a/app/components/ArtistArt.tsx b/app/components/ArtistArt.tsx index 286c729..56c9a76 100644 --- a/app/components/ArtistArt.tsx +++ b/app/components/ArtistArt.tsx @@ -1,11 +1,12 @@ -import { useAtomValue } from 'jotai/utils' -import React, { useState } from 'react' -import { ActivityIndicator, LayoutChangeEvent, StyleSheet, View } from 'react-native' -import FastImage from 'react-native-fast-image' -import LinearGradient from 'react-native-linear-gradient' +import CoverArt from '@app/components/CoverArt' import { artistArtAtomFamily } from '@app/state/music' import colors from '@app/styles/colors' -import CoverArt from '@app/components/CoverArt' +import { useLayout } from '@react-native-community/hooks' +import { useAtomValue } from 'jotai/utils' +import React from 'react' +import { ActivityIndicator, StyleSheet, View } from 'react-native' +import FastImage from 'react-native-fast-image' +import LinearGradient from 'react-native-linear-gradient' import IconFA5 from 'react-native-vector-icons/FontAwesome5' interface ArtistArtSizeProps { @@ -23,15 +24,11 @@ interface ArtistArtProps extends ArtistArtSizeProps { } const PlaceholderContainer: React.FC = ({ height, width, children }) => { - const [layout, setLayout] = useState({ x: 0, y: 0, width: 0, height: 0 }) - - const onLayout = (event: LayoutChangeEvent) => { - setLayout(event.nativeEvent.layout) - } + const layout = useLayout() return ( @@ -142,10 +139,8 @@ const ArtistArt = React.memo(({ id, height, width, round }) => { round = round === undefined ? true : round const Placeholder = () => { - const none = - - if (!artistArt || !artistArt.albumCoverUris) { - return none + if (!artistArt) { + return } const { albumCoverUris } = artistArt @@ -162,15 +157,14 @@ const ArtistArt = React.memo(({ id, height, width, round }) => { return } - return none + return } return ( diff --git a/app/components/CoverArt.tsx b/app/components/CoverArt.tsx index 21d9a2c..b568bdd 100644 --- a/app/components/CoverArt.tsx +++ b/app/components/CoverArt.tsx @@ -1,77 +1,84 @@ -import React, { useEffect, useState } from 'react' -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' +import React, { useState } from 'react' +import { ActivityIndicator, StyleSheet, View } from 'react-native' +import FastImage, { ImageStyle } from 'react-native-fast-image' import LinearGradient from 'react-native-linear-gradient' +type CoverImageProps = { + uri?: string + style?: ImageStyle + resizeMode?: keyof typeof FastImage.resizeMode + onProgress?: () => void + onLoadEnd?: () => void + onError?: () => void +} + +const CoverImage = React.memo(({ uri, style, resizeMode, onProgress, onLoadEnd, onError }) => ( + +)) + +const Fallback = React.memo<{}>(({}) => { + return +}) + const CoverArt: React.FC<{ - PlaceholderComponent?: () => JSX.Element + FallbackComponent?: () => JSX.Element placeholderIcon?: string height?: string | number width?: string | number coverArtUri?: string resizeMode?: keyof typeof FastImage.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 }) + style?: ImageStyle +}> = ({ FallbackComponent, coverArtUri, resizeMode, style }) => { + const [loading, setLoading] = useState(false) + const [fallbackVisible, setFallbackVisible] = useState(false) - useEffect(() => { - if (!coverArtUri) { - setLoading(false) - } - }, [coverArtUri, setLoading]) - - const Image = () => ( - { - setLoading(false) - setPlaceholderVisible(true) - }} - onLoadEnd={() => setLoading(false)} - /> - ) - - const Placeholder = () => ( - - - - ) - - const onLayout = (event: LayoutChangeEvent) => { - setLayout(event.nativeEvent.layout) - } + const enableLoading = React.useCallback(() => setLoading(true), []) + const disableLoading = React.useCallback(() => setLoading(false), []) + const enableFallback = React.useCallback(() => setFallbackVisible(true), []) return ( - - {coverArtUri ? : <>} - - {PlaceholderComponent ? : } - - + + + {fallbackVisible ? ( + FallbackComponent ? ( + + + + ) : ( + + ) + ) : ( + <> + )} + ) } const styles = StyleSheet.create({ - container: {}, image: { height: '100%', width: '100%', }, - placeholderContainer: { + fallback: { height: '100%', width: '100%', position: 'absolute', - }, - placeholder: { - height: '100%', - width: '100%', justifyContent: 'center', alignItems: 'center', }, diff --git a/app/components/NowPlayingBar.tsx b/app/components/NowPlayingBar.tsx index c7b216e..0c06b4e 100644 --- a/app/components/NowPlayingBar.tsx +++ b/app/components/NowPlayingBar.tsx @@ -69,8 +69,7 @@ const NowPlayingBar = () => { diff --git a/app/components/SongItem.tsx b/app/components/SongItem.tsx index f9900b3..dee9357 100644 --- a/app/components/SongItem.tsx +++ b/app/components/SongItem.tsx @@ -23,7 +23,7 @@ const SongItem: React.FC<{ return ( - {showArt ? : <>} + {showArt ? : <>} {song.title} @@ -58,6 +58,8 @@ const styles = StyleSheet.create({ }, art: { marginRight: 10, + height: 50, + width: 50, }, text: { flex: 1, diff --git a/app/screens/AlbumView.tsx b/app/screens/AlbumView.tsx index a4811fb..914e97b 100644 --- a/app/screens/AlbumView.tsx +++ b/app/screens/AlbumView.tsx @@ -28,9 +28,7 @@ const AlbumDetails: React.FC<{ imageKey={`${album.name}${album.artist}`} style={styles.container}> - - - + {album.name} {album.artist} diff --git a/app/screens/ArtistView.tsx b/app/screens/ArtistView.tsx index e786478..1a48a64 100644 --- a/app/screens/ArtistView.tsx +++ b/app/screens/ArtistView.tsx @@ -26,7 +26,7 @@ const AlbumItem = React.memo<{ navigation.navigate('AlbumView', { id: album.id, title: album.name })} style={[styles.albumItem, { width }]}> - + {album.name} {album.year ? album.year : ''} @@ -73,11 +73,9 @@ const ArtistDetails: React.FC<{ id: string }> = ({ id }) => { style={styles.scroll} contentContainerStyle={styles.scrollContent}> @@ -151,8 +149,8 @@ const styles = StyleSheet.create({ }, artistCover: { position: 'absolute', - width: '100%', height: artistCoverHeight, + width: '100%', }, albums: { width: '100%', diff --git a/app/screens/Home.tsx b/app/screens/Home.tsx index e27da57..0b81f5c 100644 --- a/app/screens/Home.tsx +++ b/app/screens/Home.tsx @@ -6,11 +6,19 @@ import { homeListsAtom, homeListsUpdatingAtom, useUpdateHomeLists } from '@app/s import { homeListTypesAtom, useActiveServerRefresh } from '@app/state/settings' import colors from '@app/styles/colors' import font from '@app/styles/font' +import { GetAlbumListType } from '@app/subsonic/params' import { useNavigation } from '@react-navigation/native' import { useAtomValue } from 'jotai/utils' import React from 'react' import { RefreshControl, ScrollView, StatusBar, StyleSheet, Text, View } from 'react-native' +const titles: { [key in GetAlbumListType]?: string } = { + recent: 'Recent Albums', + random: 'Random Albums', + frequent: 'Frequent Albums', + starred: 'Starred Albums', +} + const AlbumItem = React.memo<{ album: AlbumListItem }>(({ album }) => { @@ -21,7 +29,7 @@ const AlbumItem = React.memo<{ onPress={() => navigation.navigate('AlbumView', { id: album.id, title: album.name })} key={album.id} style={styles.item}> - + {album.name} @@ -33,7 +41,7 @@ const AlbumItem = React.memo<{ }) const Category = React.memo<{ - name: string + name?: string data: AlbumListItem[] }>(({ name, data }) => { return ( @@ -75,7 +83,7 @@ const Home = () => { }> {types.map(type => ( - + ))} diff --git a/app/screens/LibraryAlbums.tsx b/app/screens/LibraryAlbums.tsx index 4f7241e..234dc68 100644 --- a/app/screens/LibraryAlbums.tsx +++ b/app/screens/LibraryAlbums.tsx @@ -25,7 +25,7 @@ const AlbumItem = React.memo<{ navigation.navigate('AlbumView', { id, title: name })}> - + {name} diff --git a/app/screens/NowPlayingLayout.tsx b/app/screens/NowPlayingLayout.tsx index 1159d9a..d261eb3 100644 --- a/app/screens/NowPlayingLayout.tsx +++ b/app/screens/NowPlayingLayout.tsx @@ -73,7 +73,7 @@ const SongCoverArt = () => { return ( - + ) } @@ -84,6 +84,10 @@ const coverArtStyles = StyleSheet.create({ alignItems: 'center', paddingBottom: 20, }, + image: { + height: '100%', + width: '100%', + }, }) const SongInfo = () => {