feat: attempt to retrieve images from downloaded items
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo, useState } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { Dimensions, ViewProps } from 'react-native';
|
import { Dimensions, ViewProps } from 'react-native';
|
||||||
import { Canvas, Blur, Image as SkiaImage, useImage, Offset, Mask, RoundedRect, Shadow } from '@shopify/react-native-skia';
|
import { Canvas, Blur, Image as SkiaImage, useImage, Offset, Mask, RoundedRect, Shadow } from '@shopify/react-native-skia';
|
||||||
import useDefaultStyles, { useUserOrSystemScheme } from './Colors';
|
import useDefaultStyles, { useUserOrSystemScheme } from './Colors';
|
||||||
@@ -49,9 +49,8 @@ function CoverImage({
|
|||||||
}: Props) {
|
}: Props) {
|
||||||
const defaultStyles = useDefaultStyles();
|
const defaultStyles = useDefaultStyles();
|
||||||
const colorScheme = useUserOrSystemScheme();
|
const colorScheme = useUserOrSystemScheme();
|
||||||
const [hasFailed, setFailed] = useState(false);
|
|
||||||
|
|
||||||
const image = useImage(src || null, () => setFailed(true));
|
const image = useImage(src || null);
|
||||||
const fallback = useImage(colorScheme === 'light' ? emptyAlbumLight : emptyAlbumDark);
|
const fallback = useImage(colorScheme === 'light' ? emptyAlbumLight : emptyAlbumDark);
|
||||||
const { canvasSize, imageSize } = useMemo(() => {
|
const { canvasSize, imageSize } = useMemo(() => {
|
||||||
const imageSize = Screen.width - margin;
|
const imageSize = Screen.width - margin;
|
||||||
@@ -59,8 +58,6 @@ function CoverImage({
|
|||||||
return { imageSize, canvasSize };
|
return { imageSize, canvasSize };
|
||||||
}, [blurRadius, margin]);
|
}, [blurRadius, margin]);
|
||||||
|
|
||||||
console.log({ src, hasFailed });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container size={imageSize} style={style}>
|
<Container size={imageSize} style={style}>
|
||||||
<BlurContainer size={canvasSize} offset={blurRadius}>
|
<BlurContainer size={canvasSize} offset={blurRadius}>
|
||||||
|
|||||||
@@ -17,16 +17,17 @@ export const failDownload = createAction<{ id: string }>('download/fail');
|
|||||||
|
|
||||||
export const downloadTrack = createAsyncThunk(
|
export const downloadTrack = createAsyncThunk(
|
||||||
'/downloads/track',
|
'/downloads/track',
|
||||||
async (id: string, { dispatch }) => {
|
async (id: string, { dispatch, getState }) => {
|
||||||
// Generate the URL we can use to download the file
|
// Generate the URL we can use to download the file
|
||||||
|
const entity = (getState() as AppState).music.tracks.entities[id];
|
||||||
const audioUrl = generateTrackUrl(id);
|
const audioUrl = generateTrackUrl(id);
|
||||||
const imageUrl = getImage(id);
|
const imageUrl = getImage(entity);
|
||||||
|
|
||||||
// Get the content-type from the URL by doing a HEAD-only request
|
// Get the content-type from the URL by doing a HEAD-only request
|
||||||
const [audioExt, imageExt] = await Promise.all([
|
const [audioExt, imageExt] = await Promise.all([
|
||||||
getExtensionForUrl(audioUrl),
|
getExtensionForUrl(audioUrl),
|
||||||
// Image files may be absent
|
// Image files may be absent
|
||||||
getExtensionForUrl(imageUrl).catch(() => null)
|
imageUrl ? getExtensionForUrl(imageUrl).catch(() => null) : null
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Then generate the proper location
|
// Then generate the proper location
|
||||||
@@ -51,7 +52,7 @@ export const downloadTrack = createAsyncThunk(
|
|||||||
|
|
||||||
const { promise: imagePromise } = imageExt && imageLocation
|
const { promise: imagePromise } = imageExt && imageLocation
|
||||||
? downloadFile({
|
? downloadFile({
|
||||||
fromUrl: imageUrl,
|
fromUrl: imageUrl!,
|
||||||
toFile: imageLocation,
|
toFile: imageLocation,
|
||||||
background: true,
|
background: true,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -112,25 +112,36 @@ function formatImageUri(ItemId: string | number, baseUri: string): string {
|
|||||||
*/
|
*/
|
||||||
export function getImage(item: string | number | Album | AlbumTrack | Playlist | ArtistItem | null, credentials?: AppState['settings']['credentials']): string | undefined {
|
export function getImage(item: string | number | Album | AlbumTrack | Playlist | ArtistItem | null, credentials?: AppState['settings']['credentials']): string | undefined {
|
||||||
// Either accept provided credentials, or retrieve them directly from the store
|
// Either accept provided credentials, or retrieve them directly from the store
|
||||||
const { uri: serverUri } = credentials
|
const state = asyncFetchStore().getState();
|
||||||
?? asyncFetchStore().getState().settings.credentials ?? {};
|
const { uri: serverUri } = credentials ?? state.settings.credentials ?? {};
|
||||||
|
|
||||||
if (!item || !serverUri) {
|
if (!item || !serverUri) {
|
||||||
return undefined;
|
return undefined;
|
||||||
// GUARD: If the item's just the id, we'll pass it on directly.
|
}
|
||||||
} else if (typeof item === 'string' || typeof item === 'number') {
|
|
||||||
|
// Get the item ID
|
||||||
|
const itemId = typeof item === 'string' || typeof item === 'number'
|
||||||
|
? item
|
||||||
|
: 'PrimaryImageItemId' in item
|
||||||
|
? item.PrimaryImageItemId || item.Id
|
||||||
|
: item.Id;
|
||||||
|
|
||||||
|
// Check if we have a downloaded image for this item
|
||||||
|
const downloadEntity = state.downloads.entities[itemId];
|
||||||
|
if (downloadEntity?.image) {
|
||||||
|
return downloadEntity.image;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no downloaded image, fall back to server URL
|
||||||
|
if (typeof item === 'string' || typeof item === 'number') {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
console.warn('useGetImage: supplied item is string or number. Please submit an item object instead.', { item });
|
console.warn('useGetImage: supplied item is string or number. Please submit an item object instead.', { item });
|
||||||
}
|
}
|
||||||
return formatImageUri(item, serverUri);
|
return formatImageUri(item, serverUri);
|
||||||
// GUARD: If the item has an `PrimaryImageItemId` (for Emby servers),
|
|
||||||
// we'll attemp to return that
|
|
||||||
} else if ('PrimaryImageItemId' in item) {
|
} else if ('PrimaryImageItemId' in item) {
|
||||||
return formatImageUri(item.PrimaryImageItemId || item.Id, serverUri);
|
return formatImageUri(item.PrimaryImageItemId || item.Id, serverUri);
|
||||||
} else {
|
} else if ('ImageTags' in item && item.ImageTags.Primary) {
|
||||||
if ('ImageTags' in item && item.ImageTags.Primary) {
|
return formatImageUri(item.Id, serverUri);
|
||||||
return formatImageUri(item.Id, serverUri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user