ChannelThumbnail fixes #6075

Merged
infinite-persistence merged 4 commits from ip/reenable-channel-thumbnail-optimization into master 2021-05-17 21:51:21 +02:00
2 changed files with 28 additions and 4 deletions

View file

@ -5,6 +5,8 @@ import classnames from 'classnames';
import Gerbil from './gerbil.png'; import Gerbil from './gerbil.png';
import FreezeframeWrapper from 'component/fileThumbnail/FreezeframeWrapper'; import FreezeframeWrapper from 'component/fileThumbnail/FreezeframeWrapper';
import ChannelStakedIndicator from 'component/channelStakedIndicator'; import ChannelStakedIndicator from 'component/channelStakedIndicator';
import { getThumbnailCdnUrl } from 'util/thumbnail';
import useLazyLoading from 'effects/use-lazy-loading';
type Props = { type Props = {
thumbnail: ?string, thumbnail: ?string,
@ -20,6 +22,7 @@ type Props = {
showDelayedMessage?: boolean, showDelayedMessage?: boolean,
hideStakedIndicator?: boolean, hideStakedIndicator?: boolean,
xsmall?: boolean, xsmall?: boolean,
noOptimization?: boolean,
}; };
function ChannelThumbnail(props: Props) { function ChannelThumbnail(props: Props) {
@ -37,13 +40,16 @@ function ChannelThumbnail(props: Props) {
isResolving, isResolving,
showDelayedMessage = false, showDelayedMessage = false,
hideStakedIndicator = false, hideStakedIndicator = false,
noOptimization,
} = props; } = props;
const [thumbError, setThumbError] = React.useState(false); const [thumbError, setThumbError] = React.useState(false);
const shouldResolve = claim === undefined; const shouldResolve = claim === undefined;
const thumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://'); const thumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://');
const thumbnailPreview = rawThumbnailPreview && rawThumbnailPreview.trim().replace(/^http:\/\//i, 'https://'); const thumbnailPreview = rawThumbnailPreview && rawThumbnailPreview.trim().replace(/^http:\/\//i, 'https://');
const channelThumbnail = thumbnail || thumbnailPreview; const channelThumbnail = thumbnail || thumbnailPreview;
const isGif = channelThumbnail && channelThumbnail.endsWith('gif');
const showThumb = (!obscure && !!thumbnail) || thumbnailPreview; const showThumb = (!obscure && !!thumbnail) || thumbnailPreview;
const thumbnailRef = React.useRef(null);
// Generate a random color class based on the first letter of the channel name // Generate a random color class based on the first letter of the channel name
const { channelName } = parseURI(uri); const { channelName } = parseURI(uri);
let initializer; let initializer;
@ -61,7 +67,9 @@ function ChannelThumbnail(props: Props) {
} }
}, [doResolveUri, shouldResolve, uri]); }, [doResolveUri, shouldResolve, uri]);
if (channelThumbnail && channelThumbnail.endsWith('gif') && !allowGifs) { useLazyLoading(thumbnailRef, 0.25, [showThumb, thumbError, channelThumbnail]);
if (isGif && !allowGifs) {
return ( return (
<FreezeframeWrapper src={channelThumbnail} className={classnames('channel-thumbnail', className)}> <FreezeframeWrapper src={channelThumbnail} className={classnames('channel-thumbnail', className)}>
{!hideStakedIndicator && <ChannelStakedIndicator uri={uri} claim={claim} />} {!hideStakedIndicator && <ChannelStakedIndicator uri={uri} claim={claim} />}
@ -69,6 +77,14 @@ function ChannelThumbnail(props: Props) {
); );
} }
let url = channelThumbnail;
// @if TARGET='web'
// Pass image urls through a compression proxy, except for GIFs.
if (thumbnail && !noOptimization && !(isGif && allowGifs)) {
url = getThumbnailCdnUrl({ thumbnail });
}
// @endif
return ( return (
<div <div
className={classnames('channel-thumbnail', className, { className={classnames('channel-thumbnail', className, {
@ -80,9 +96,10 @@ function ChannelThumbnail(props: Props) {
> >
{!showThumb && ( {!showThumb && (
<img <img
ref={thumbnailRef}
alt={__('Channel profile picture')} alt={__('Channel profile picture')}
className="channel-thumbnail__default" className="channel-thumbnail__default"
src={!thumbError && thumbnailPreview ? thumbnailPreview : Gerbil} data-src={!thumbError && url ? url : Gerbil}
onError={() => setThumbError(true)} // if thumb fails (including due to https replace, show gerbil. onError={() => setThumbError(true)} // if thumb fails (including due to https replace, show gerbil.
/> />
)} )}
@ -92,9 +109,10 @@ function ChannelThumbnail(props: Props) {
<div className="chanel-thumbnail--waiting">{__('This will be visible in a few minutes.')}</div> <div className="chanel-thumbnail--waiting">{__('This will be visible in a few minutes.')}</div>
) : ( ) : (
<img <img
ref={thumbnailRef}
alt={__('Channel profile picture')} alt={__('Channel profile picture')}
className="channel-thumbnail__custom" className="channel-thumbnail__custom"
src={!thumbError ? thumbnailPreview || thumbnail : Gerbil} data-src={!thumbError && url ? url : Gerbil}
onError={() => setThumbError(true)} // if thumb fails (including due to https replace, show gerbil. onError={() => setThumbError(true)} // if thumb fails (including due to https replace, show gerbil.
/> />
)} )}

View file

@ -168,7 +168,13 @@ function ChannelPage(props: Props) {
</div> </div>
{cover && <img className={classnames('channel-cover__custom')} src={cover} />} {cover && <img className={classnames('channel-cover__custom')} src={cover} />}
<div className="channel__primary-info"> <div className="channel__primary-info">
<ChannelThumbnail className="channel__thumbnail--channel-page" uri={uri} allowGifs hideStakedIndicator /> <ChannelThumbnail
className="channel__thumbnail--channel-page"
uri={uri}
allowGifs
hideStakedIndicator
noOptimization
/>
<h1 className="channel__title"> <h1 className="channel__title">
{title || '@' + channelName} {title || '@' + channelName}
<ChannelStakedIndicator uri={uri} large /> <ChannelStakedIndicator uri={uri} large />