Skip to content

Commit

Permalink
Fix: re-rendering ImageError
Browse files Browse the repository at this point in the history
  • Loading branch information
sawyerf committed Dec 27, 2024
1 parent 73bc9d2 commit 2b8fe04
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 97 deletions.
2 changes: 1 addition & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Castafiore",
"slug": "Castafiore",
"description": "Mobile app for navidrome",
"version": "2024.12.25",
"version": "2024.12.27",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
Expand Down
13 changes: 4 additions & 9 deletions app/components/ImageError.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ import { Image } from 'react-native'

const ImageError = ({ source, style, children }) => {
const [isImage, setIsImage] = React.useState(true)
const image = React.useMemo(() => {
return <Image source={source} onError={() => setIsImage(false)} style={style} />
}, [source?.uri, style])

React.useEffect(() => {
if (!source?.uri) setIsImage(false)
else setIsImage(true)
}, [source?.uri])

if (isImage) {
return (
<Image
source={source}
onError={() => setIsImage(false)}
style={style}
/>
)
}
if (isImage) return image
return children
}

Expand Down
10 changes: 3 additions & 7 deletions app/components/player/BoxDesktopPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@ import Icon from 'react-native-vector-icons/FontAwesome';
import { ConfigContext } from '~/contexts/config';
import { SongContext } from '~/contexts/song';
import { ThemeContext } from '~/contexts/theme';
import { nextSong, pauseSong, resumeSong, previousSong, setPosition, secondToTime, setVolume, getVolume, updateVolume, setRepeat, updateTime } from '~/utils/player';
import { nextSong, pauseSong, resumeSong, previousSong, setPosition, secondToTime, setVolume, updateVolume, setRepeat, updateTime } from '~/utils/player';
import { urlCover } from '~/utils/api';
import IconButton from '~/components/button/IconButton';
import ImageError from '~/components/ImageError';
import SlideBar from '~/components/button/SlideBar';

const BoxDesktopPlayer = ({ fullscreen }) => {
const [song, songDispatch] = React.useContext(SongContext)
const [volume, setVol] = React.useState(getVolume())
const config = React.useContext(ConfigContext)
const theme = React.useContext(ThemeContext)
const time = updateTime()

React.useEffect(() => {
return updateVolume(setVol)
}, [])

const volume = updateVolume()

return (
<View
style={{
Expand Down
10 changes: 5 additions & 5 deletions app/components/player/FullScreenPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ const preview = {
}

const FullScreenPlayer = ({ fullscreen }) => {
const config = React.useContext(ConfigContext)
const theme = React.useContext(ThemeContext)
const [isPreview, setIsPreview] = React.useState(preview.COVER)
const [lyrics, setLyrics] = React.useState([])
const [song, songDispatch] = React.useContext(SongContext)
const config = React.useContext(ConfigContext)
const insets = useSafeAreaInsets();
const [lyrics, setLyrics] = React.useState([])
const [isPreview, setIsPreview] = React.useState(preview.COVER)
const theme = React.useContext(ThemeContext)
const time = updateTime()

React.useEffect(() => {
Expand Down Expand Up @@ -120,7 +120,7 @@ const FullScreenPlayer = ({ fullscreen }) => {
if (index < lyrics.length - 2 && time.position >= lyrics[index + 2]?.time) return null
const isCurrent = time.position >= lyric.time && (lyrics.length == index + 1 || time.position < lyrics[index + 1]?.time)
return (
<View style={{
<View key={index} style={{
display: 'flex',
justifyContent: 'flex-end',
minHeight: ((time.position > lyric.time && !isCurrent) || !index) ? 62 : 0,
Expand Down
25 changes: 11 additions & 14 deletions app/screens/Album.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Text, View, Image, ScrollView, TouchableOpacity } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import { ConfigContext } from '~/contexts/config';
import { getCachedAndApi } from '~/utils/api';
import { useCachedAndApi } from '~/utils/api';
import { ThemeContext } from '~/contexts/theme';
import { urlCover } from '~/utils/api';
import BackButton from '~/components/button/BackButton';
Expand All @@ -15,22 +15,19 @@ import SongsList from '~/components/lists/SongsList';

const Album = ({ navigation, route }) => {
const insets = useSafeAreaInsets();
const [songs, setSongs] = React.useState([]);
const config = React.useContext(ConfigContext)
const theme = React.useContext(ThemeContext)

React.useEffect(() => {
getCachedAndApi(config, 'getAlbum', `id=${route.params.album.id}`, (json) => {
setSongs(json?.album?.song.sort((a, b) => {
// sort by discNumber and track
if (a.discNumber < b.discNumber) return -1;
if (a.discNumber > b.discNumber) return 1;
if (a.track < b.track) return -1;
if (a.track > b.track) return 1;
return 0;
}))
})
}, [config, route.params.album])
const songs = useCachedAndApi([], 'getAlbum', `id=${route.params.album.id}`, (json, setData) => {
setData(json?.album?.song.sort((a, b) => {
// sort by discNumber and track
if (a.discNumber < b.discNumber) return -1;
if (a.discNumber > b.discNumber) return 1;
if (a.track < b.track) return -1;
if (a.track > b.track) return 1;
return 0;
}))
}, [route.params.album])

return (
<ScrollView
Expand Down
27 changes: 7 additions & 20 deletions app/screens/Artist.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SongContext } from '~/contexts/song';
import { ConfigContext } from '~/contexts/config';
import { ThemeContext } from '~/contexts/theme';
import { playSong } from '~/utils/player';
import { getApi, urlCover, getCachedAndApi } from '~/utils/api';
import { getApi, urlCover, useCachedAndApi } from '~/utils/api';
import { shuffle } from '~/utils/tools';
import mainStyles from '~/styles/main';
import presStyles from '~/styles/pres';
Expand All @@ -18,24 +18,18 @@ import IconButton from '~/components/button/IconButton';

const Artist = ({ route }) => {
const insets = useSafeAreaInsets();
const [artist, setArtist] = React.useState([]);
const [artistInfo, setArtistInfo] = React.useState([]);
const [song, songDispatch] = React.useContext(SongContext)
const allSongs = React.useRef([])
const config = React.useContext(ConfigContext)
const theme = React.useContext(ThemeContext)

const getArtistInfo = () => {
getCachedAndApi(config, 'getArtistInfo', `id=${route.params.artist.id}`, (json) => {
setArtistInfo(json.artistInfo)
})
}
const artistInfo = useCachedAndApi([], 'getArtistInfo', `id=${route.params.artist.id}`, (json, setData) => {
setData(json.artistInfo)
}, [route.params.artist])

const getArtist = () => {
getCachedAndApi(config, 'getArtist', `id=${route.params.artist.id}`, (json) => {
setArtist(json.artist)
})
}
const artist = useCachedAndApi([], 'getArtist', `id=${route.params.artist.id}`, (json, setData) => {
setData(json.artist)
}, [route.params.artist])

const getRandomSongs = async () => {
if (!artist.album) return
Expand Down Expand Up @@ -71,13 +65,6 @@ const Artist = ({ route }) => {
.catch((error) => { })
}

React.useEffect(() => {
if (config.query) {
getArtist()
getArtistInfo()
}
}, [config, route.params.artist])

return (
<ScrollView
style={{
Expand Down
29 changes: 8 additions & 21 deletions app/screens/Genre.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Icon from 'react-native-vector-icons/FontAwesome';

import { ConfigContext } from '~/contexts/config';
import { getApi } from '~/utils/api';
import { getCachedAndApi } from '~/utils/api';
import { useCachedAndApi } from '~/utils/api';
import { playSong } from '~/utils/player';
import { SongContext } from '~/contexts/song';
import { ThemeContext } from '~/contexts/theme';
Expand All @@ -20,16 +20,15 @@ const Genre = ({ route }) => {
const insets = useSafeAreaInsets();
const config = React.useContext(ConfigContext)
const [song, songDispatch] = React.useContext(SongContext)
const [albums, setAlbums] = React.useState([]);
const [songs, setSongs] = React.useState([]);
const theme = React.useContext(ThemeContext)

React.useEffect(() => {
if (config.query) {
getAlbumsByGenre()
getSongs()
}
}, [config])
const albums = useCachedAndApi([], 'getAlbumList', { type: 'byGenre', genre: route.params.genre.value }, (json, setData) => {
setData(json?.albumList?.album)
})

const songs = useCachedAndApi([], 'getSongsByGenre', { genre: route.params.genre.value, count: 50 }, (json, setData) => {
setData(json?.songsByGenre?.song)
})

const getRandomSongs = () => {
getApi(config, 'getRandomSongs', { genre: route.params.genre.value, count: 50 })
Expand All @@ -41,18 +40,6 @@ const Genre = ({ route }) => {
.catch((error) => { })
}

const getAlbumsByGenre = () => {
getCachedAndApi(config, 'getAlbumList', { type: 'byGenre', genre: route.params.genre.value }, (json) => {
setAlbums(json?.albumList?.album)
})
}

const getSongs = () => {
getCachedAndApi(config, 'getSongsByGenre', { genre: route.params.genre.value, count: 50 }, (json) => {
setSongs(json?.songsByGenre?.song)
})
}

return (
<ScrollView
contentContainerStyle={mainStyles.contentMainContainer(insets)}
Expand Down
8 changes: 4 additions & 4 deletions app/screens/tabs/Playlists.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { Animated, ScrollView, Text, TextInput, TouchableOpacity, View } from 'r
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import Icon from 'react-native-vector-icons/FontAwesome';

import IconButton from '~/components/button/IconButton';
import SongsList from '~/components/lists/SongsList';
import VerticalPlaylist from '~/components/lists/VerticalPlaylist';
import { ConfigContext } from '~/contexts/config';
import { getCachedAndApi } from '~/utils/api';
import { SettingsContext } from '~/contexts/settings';
import { ThemeContext } from '~/contexts/theme';
import IconButton from '~/components/button/IconButton';
import mainStyles from '~/styles/main';
import { getCachedAndApi } from '~/utils/api';
import SongsList from '~/components/lists/SongsList';
import VerticalPlaylist from '~/components/lists/VerticalPlaylist';


const Playlists = ({ navigation }) => {
Expand Down
2 changes: 1 addition & 1 deletion app/screens/tabs/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import mainStyles from '~/styles/main';
import SongsList from '~/components/lists/SongsList';


const Search = ({ navigation }) => {
const Search = () => {
const insets = useSafeAreaInsets();
const config = React.useContext(ConfigContext)
const theme = React.useContext(ThemeContext)
Expand Down
2 changes: 1 addition & 1 deletion app/services/serviceWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ registerRoute(
({ url }) => {
return url.hostname === "lrclib.net" || url.pathname.match(/\/rest\/getLyricsBySongId$/)
},
new NetworkFirst({
new CacheFirst({
cacheName: "lyrics",
})
)
Expand Down
15 changes: 15 additions & 0 deletions app/utils/api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import AsyncStorage from "@react-native-async-storage/async-storage"
import React from "react"
import { ConfigContext } from "~/contexts/config"

const getUrl = (config, path, query = '') => {
let encodedQuery = ''
Expand Down Expand Up @@ -56,6 +58,19 @@ export const getCachedAndApi = async (config, path, query = '', setData = (json)
.catch((error) => { })
}

export const useCachedAndApi = (initialState, path, query = '', setFunc = (json, setData) => { }, deps = []) => {
const config = React.useContext(ConfigContext)
const [data, setData] = React.useState(initialState)

React.useEffect(() => {
getCachedAndApi(config, path, query, (json) => {
setFunc(json, setData)
})
}, [config, ...deps])

return data
}

export const urlCover = (config, id, size = null) => {
if (id === 'tuktuktuk') return 'https://github.com/sawyerf/Castafiore/blob/main/assets/icon.png?raw=true'
if (!config?.url || !config?.query) return null
Expand Down
2 changes: 1 addition & 1 deletion app/utils/player.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export const tuktuktuk = async (songDispatch) => {
}
}

export const updateVolume = (setVolume) => { }
export const updateVolume = () => { }
export const updateTime = () => {
return useProgress(500)
}
28 changes: 18 additions & 10 deletions app/utils/player.web.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ export const initPlayer = async (songDispatch) => {
}

export const updateTime = () => {
const [time, setTime] = React.useState({ position: 0, duration: 0 })
const [time, setTime] = React.useState({
position: audio().currentTime,
duration: audio().duration,
})

React.useEffect(() => {
const sound = audio()
Expand Down Expand Up @@ -182,17 +185,22 @@ export const getVolume = () => {
return audio().volume
}

export const updateVolume = (setVolume) => {
const sound = audio()
export const updateVolume = () => {
const [volume, setVol] = React.useState(getVolume())

const volumeChangeHandler = () => {
setVolume(sound.volume)
}
React.useEffect(() => {
const sound = audio()
const volumeChangeHandler = () => {
setVol(sound.volume)
}

sound.addEventListener('volumechange', volumeChangeHandler)
return () => {
sound.removeEventListener('volumechange', volumeChangeHandler)
}
sound.addEventListener('volumechange', volumeChangeHandler)
return () => {
sound.removeEventListener('volumechange', volumeChangeHandler)
}
}, [])

return volume
}

export const secondToTime = (second) => {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "castafiore",
"version": "2024.12.25",
"version": "2024.12.27",
"main": "index.js",
"homepage": ".",
"scripts": {
Expand Down

0 comments on commit 2b8fe04

Please sign in to comment.