set debounce / viewport for images used in the app

This commit is contained in:
jeffvli
2026-01-28 19:49:37 -08:00
parent 23990b581b
commit bd34a729b3
10 changed files with 39 additions and 10 deletions
@@ -119,6 +119,9 @@ const CarouselItem = ({ album }: CarouselItemProps) => {
<ItemImage <ItemImage
className={styles.albumImage} className={styles.albumImage}
containerClassName={styles.albumImageContainer} containerClassName={styles.albumImageContainer}
enableDebounce={false}
enableViewport={false}
fetchPriority="high"
id={album.imageId} id={album.imageId}
itemType={LibraryItem.ALBUM} itemType={LibraryItem.ALBUM}
src={imageUrl} src={imageUrl}
@@ -116,8 +116,11 @@ const CarouselItem = ({ album }: CarouselItemProps) => {
<ItemImage <ItemImage
className={styles.albumImage} className={styles.albumImage}
containerClassName={styles.albumImageContainer} containerClassName={styles.albumImageContainer}
enableDebounce={false}
enableViewport={false}
id={album.imageId} id={album.imageId}
itemType={LibraryItem.ALBUM} itemType={LibraryItem.ALBUM}
fetchPriority="high"
type="itemCard" type="itemCard"
/> />
<div className={styles.playButtonOverlay}> <div className={styles.playButtonOverlay}>
@@ -333,6 +333,7 @@ const CompactItemCard = ({
className={clsx(styles.image, { className={clsx(styles.image, {
[styles.isRound]: isRound, [styles.isRound]: isRound,
})} })}
enableDebounce={false}
id={data?.imageId} id={data?.imageId}
itemType={itemType} itemType={itemType}
src={(data as Album | AlbumArtist | Playlist | Song)?.imageUrl} src={(data as Album | AlbumArtist | Playlist | Song)?.imageUrl}
@@ -553,6 +554,7 @@ const DefaultItemCard = ({
<> <>
<ItemImage <ItemImage
className={clsx(styles.image, { [styles.isRound]: isRound })} className={clsx(styles.image, { [styles.isRound]: isRound })}
enableDebounce={false}
id={data?.imageId} id={data?.imageId}
itemType={itemType} itemType={itemType}
src={(data as Album | AlbumArtist | Playlist | Song)?.imageUrl} src={(data as Album | AlbumArtist | Playlist | Song)?.imageUrl}
@@ -835,6 +837,7 @@ const PosterItemCard = ({
<> <>
<ItemImage <ItemImage
className={clsx(styles.image, { [styles.isRound]: isRound })} className={clsx(styles.image, { [styles.isRound]: isRound })}
enableDebounce={false}
id={(data as { imageId: string })?.imageId} id={(data as { imageId: string })?.imageId}
itemType={itemType} itemType={itemType}
src={(data as { imageUrl: string })?.imageUrl} src={(data as { imageUrl: string })?.imageUrl}
@@ -87,6 +87,8 @@ const ImageColumnBase = (props: ItemTableListInnerColumn) => {
[styles.imageContainerWithAspectRatio]: [styles.imageContainerWithAspectRatio]:
props.size === 'default' || props.size === 'large', props.size === 'default' || props.size === 'large',
})} })}
enableDebounce={true}
enableViewport={false}
id={item?.imageId} id={item?.imageId}
itemType={item?._itemType} itemType={item?._itemType}
src={item?.imageUrl} src={item?.imageUrl}
@@ -103,6 +103,8 @@ export const DefaultTitleCombinedColumn = (props: ItemTableListInnerColumn) => {
> >
<ItemImage <ItemImage
containerClassName={styles.image} containerClassName={styles.image}
enableDebounce={true}
enableViewport={false}
id={item?.imageId} id={item?.imageId}
itemType={item?._itemType} itemType={item?._itemType}
src={item?.imageUrl} src={item?.imageUrl}
@@ -121,9 +121,11 @@ export const LeftControls = () => {
styles.playerbarImage, styles.playerbarImage,
PlaybackSelectors.playerCoverArt, PlaybackSelectors.playerCoverArt,
)} )}
enableDebounce={false}
enableViewport={false}
fetchPriority="high"
id={currentSong?.imageId} id={currentSong?.imageId}
itemType={LibraryItem.SONG} itemType={LibraryItem.SONG}
loading="eager"
serverId={currentSong?._serverId} serverId={currentSong?._serverId}
type="table" type="table"
/> />
@@ -92,9 +92,11 @@ export const MobilePlayerbar = () => {
styles.playerbarImage, styles.playerbarImage,
PlaybackSelectors.playerCoverArt, PlaybackSelectors.playerCoverArt,
)} )}
enableDebounce={false}
enableViewport={false}
fetchPriority="high"
id={currentSong.imageId} id={currentSong.imageId}
itemType={LibraryItem.SONG} itemType={LibraryItem.SONG}
loading="eager"
type="table" type="table"
/> />
</Tooltip> </Tooltip>
@@ -105,6 +105,9 @@ export const LibraryHeader = forwardRef(
> >
<BaseImage <BaseImage
alt="cover" alt="cover"
enableDebounce={false}
enableViewport={false}
fetchPriority="high"
src={imageUrl} src={imageUrl}
style={{ style={{
maxHeight: '100%', maxHeight: '100%',
@@ -137,6 +140,9 @@ export const LibraryHeader = forwardRef(
<ItemImage <ItemImage
className={styles.image} className={styles.image}
containerClassName={styles.image} containerClassName={styles.image}
enableDebounce={false}
enableViewport={false}
fetchPriority="high"
id={item.imageId} id={item.imageId}
itemType={item.type as LibraryItem} itemType={item.type as LibraryItem}
onError={onImageError} onError={onImageError}
@@ -51,6 +51,8 @@ export function ArtistMultiSelectRow({
> >
<ItemImage <ItemImage
containerClassName={styles.rowImage} containerClassName={styles.rowImage}
enableDebounce={true}
enableViewport={false}
itemType={LibraryItem.ARTIST} itemType={LibraryItem.ARTIST}
src={options[index].imageUrl} src={options[index].imageUrl}
type="table" type="table"
+12 -8
View File
@@ -94,11 +94,13 @@ export function BaseImage({
); );
} }
const { className: containerPropsClassName, ...restContainerProps } = imageContainerProps || {};
return ( return (
<ImageContainer <ImageContainer
className={containerClassName} className={clsx(containerClassName, containerPropsClassName)}
enableAnimation={enableAnimation} enableAnimation={enableAnimation}
{...imageContainerProps} {...restContainerProps}
> >
{src ? ( {src ? (
<Img <Img
@@ -140,14 +142,15 @@ function ImageWithDebounce({
const [debouncedSrc] = useDebouncedValue(src, 150, { waitForInitial: true }); const [debouncedSrc] = useDebouncedValue(src, 150, { waitForInitial: true });
const viewport = useInViewport(); const viewport = useInViewport();
const { inViewport, ref } = enableViewport ? viewport : { inViewport: true, ref: undefined }; const { inViewport, ref } = enableViewport ? viewport : { inViewport: true, ref: undefined };
const { className: containerPropsClassName, ...restContainerProps } = imageContainerProps || {};
if (enableViewport) { if (enableViewport) {
return ( return (
<ImageContainer <ImageContainer
className={containerClassName} className={clsx(containerClassName, containerPropsClassName)}
enableAnimation={enableAnimation} enableAnimation={enableAnimation}
ref={ref} ref={ref}
{...imageContainerProps} {...restContainerProps}
> >
{inViewport && debouncedSrc ? ( {inViewport && debouncedSrc ? (
<Img <Img
@@ -177,9 +180,9 @@ function ImageWithDebounce({
return ( return (
<ImageContainer <ImageContainer
className={containerClassName} className={clsx(containerClassName, containerPropsClassName)}
enableAnimation={enableAnimation} enableAnimation={enableAnimation}
{...imageContainerProps} {...restContainerProps}
> >
{debouncedSrc ? ( {debouncedSrc ? (
<Img <Img
@@ -219,13 +222,14 @@ function ImageWithViewport({
...props ...props
}: ImageProps) { }: ImageProps) {
const { inViewport, ref } = useInViewport(); const { inViewport, ref } = useInViewport();
const { className: containerPropsClassName, ...restContainerProps } = imageContainerProps || {};
return ( return (
<ImageContainer <ImageContainer
className={containerClassName} className={clsx(containerClassName, containerPropsClassName)}
enableAnimation={enableAnimation} enableAnimation={enableAnimation}
ref={ref} ref={ref}
{...imageContainerProps} {...restContainerProps}
> >
{inViewport && src ? ( {inViewport && src ? (
<Img <Img