diff --git a/.env.defaults b/.env.defaults index 5274f8c68..48c0ebb66 100644 --- a/.env.defaults +++ b/.env.defaults @@ -52,6 +52,7 @@ YRBL_SAD_IMG_URL=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-sad/c2d9649 #LOGO_TEXT_LIGHT=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-sad/c2d9649633d974e5ffb503925e1f17d951f1bd0f/f262dd #LOGO_TEXT_DARK=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-sad/c2d9649633d974e5ffb503925e1f17d951f1bd0f/f262dd #AVATAR_DEFAULT= +#MISSING_THUMB_DEFAULT= #FAVICON= # LOCALE diff --git a/config.js b/config.js index 89c916654..49e215c5b 100644 --- a/config.js +++ b/config.js @@ -35,6 +35,7 @@ const config = { LOGO_TEXT_LIGHT: process.env.LOGO_TEXT_LIGHT, LOGO_TEXT_DARK: process.env.LOGO_TEXT_DARK, AVATAR_DEFAULT: process.env.AVATAR_DEFAULT, + MISSING_THUMB_DEFAULT: process.env.MISSING_THUMB_DEFAULT, // OG OG_TITLE_SUFFIX: process.env.OG_TITLE_SUFFIX, OG_HOMEPAGE_TITLE: process.env.OG_HOMEPAGE_TITLE, diff --git a/ui/component/fileThumbnail/thumb.jsx b/ui/component/fileThumbnail/thumb.jsx index 64f11c138..9f2fb993e 100644 --- a/ui/component/fileThumbnail/thumb.jsx +++ b/ui/component/fileThumbnail/thumb.jsx @@ -6,14 +6,16 @@ import useLazyLoading from 'effects/use-lazy-loading'; type Props = { thumb: string, + fallback: ?string, children?: Node, className?: string, }; const Thumb = (props: Props) => { - const { thumb, children, className } = props; + const { thumb, fallback, children, className } = props; const thumbnailRef = React.useRef(null); - useLazyLoading(thumbnailRef); + + useLazyLoading(thumbnailRef, fallback || ''); return (
diff --git a/ui/component/fileThumbnail/view.jsx b/ui/component/fileThumbnail/view.jsx index 6da4e513c..a5ef83ab6 100644 --- a/ui/component/fileThumbnail/view.jsx +++ b/ui/component/fileThumbnail/view.jsx @@ -4,6 +4,7 @@ import { getThumbnailCdnUrl } from 'util/thumbnail'; import React from 'react'; import FreezeframeWrapper from './FreezeframeWrapper'; import Placeholder from './placeholder.png'; +import { MISSING_THUMB_DEFAULT } from 'config'; import classnames from 'classnames'; import Thumb from './thumb'; @@ -42,6 +43,8 @@ function FileThumbnail(props: Props) { ); } + const fallback = MISSING_THUMB_DEFAULT ? getThumbnailCdnUrl({ thumbnail: MISSING_THUMB_DEFAULT }) : undefined; + let url = thumbnail || (hasResolvedClaim ? Placeholder : ''); // @if TARGET='web' // Pass image urls through a compression proxy @@ -54,7 +57,7 @@ function FileThumbnail(props: Props) { if (hasResolvedClaim || thumbnailUrl) { return ( - + {children} ); diff --git a/ui/effects/use-lazy-loading.js b/ui/effects/use-lazy-loading.js index 8e9ed8555..18ac92be5 100644 --- a/ui/effects/use-lazy-loading.js +++ b/ui/effects/use-lazy-loading.js @@ -5,11 +5,13 @@ import React, { useEffect } from 'react'; /** * Helper React hook for lazy loading images * @param elementRef - A React useRef instance to the element to lazy load. + * @param backgroundFallback * @param yOffsetPx - Number of pixels from the viewport to start loading. * @param {Array<>} [deps=[]] - The dependencies this lazy-load is reliant on. */ export default function useLazyLoading( elementRef: { current: ?ElementRef }, + backgroundFallback: string = '', yOffsetPx: number = 500, deps: Array = [] ) { @@ -42,11 +44,19 @@ export default function useLazyLoading( // $FlowFixMe target.src = target.dataset.src; setSrcLoaded(true); + // No fallback handling here (clients have access to 'onerror' on the image ref). return; } // useful for lazy loading background images on divs if (target.dataset.backgroundImage) { + if (backgroundFallback) { + const tmpImage = new Image(); + tmpImage.onerror = () => { + target.style.backgroundImage = `url(${backgroundFallback})`; + }; + tmpImage.src = target.dataset.backgroundImage; + } target.style.backgroundImage = `url(${target.dataset.backgroundImage})`; } }