TelegramPWA/src/components/left/settings/WallpaperTile.tsx
Alexander Zinchuk e1cf508eca Revert "[Perf] Use canvas for faster blur (#1100)"
This reverts commit 27cc33b5541e6f9fe27cf74220e8629a5966d339.
2021-05-24 16:01:21 +03:00

115 lines
3.4 KiB
TypeScript

import React, {
FC, memo, useCallback, useEffect, useState,
} from '../../../lib/teact/teact';
import { ApiWallpaper } from '../../../api/types';
import { UPLOADING_WALLPAPER_SLUG } from '../../../types';
import { CUSTOM_BG_CACHE_NAME } from '../../../config';
import * as cacheApi from '../../../util/cacheApi';
import { fetchBlob } from '../../../util/files';
import useTransitionForMedia from '../../../hooks/useTransitionForMedia';
import buildClassName from '../../../util/buildClassName';
import useMedia from '../../../hooks/useMedia';
import useMediaWithDownloadProgress from '../../../hooks/useMediaWithDownloadProgress';
import useShowTransition from '../../../hooks/useShowTransition';
import usePrevious from '../../../hooks/usePrevious';
import useBlur from '../../../hooks/useBlur';
import ProgressSpinner from '../../ui/ProgressSpinner';
import './WallpaperTile.scss';
type OwnProps = {
wallpaper: ApiWallpaper;
isSelected: boolean;
onClick: (slug: string) => void;
};
const ANIMATION_DURATION = 300;
const WallpaperTile: FC<OwnProps> = ({
wallpaper,
isSelected,
onClick,
}) => {
const { slug, document } = wallpaper;
const localMediaHash = `wallpaper${document.id!}`;
const localBlobUrl = document.previewBlobUrl;
const previewBlobUrl = useMedia(`${localMediaHash}?size=m`);
const thumbDataUri = useBlur(
document.thumbnail && document.thumbnail.dataUri,
Boolean(previewBlobUrl),
ANIMATION_DURATION,
);
const {
shouldRenderThumb, shouldRenderFullMedia, transitionClassNames,
} = useTransitionForMedia(previewBlobUrl || localBlobUrl, 'slow');
const [isDownloadAllowed, setIsDownloadAllowed] = useState(false);
const {
mediaData: fullMedia, downloadProgress,
} = useMediaWithDownloadProgress(localMediaHash, !isDownloadAllowed);
const wasDownloadDisabled = usePrevious(isDownloadAllowed) === false;
const { shouldRender: shouldRenderSpinner, transitionClassNames: spinnerClassNames } = useShowTransition(
(isDownloadAllowed && !fullMedia) || slug === UPLOADING_WALLPAPER_SLUG,
undefined,
wasDownloadDisabled,
'slow',
);
const handleSelect = useCallback(() => {
(async () => {
const blob = await fetchBlob(fullMedia!);
await cacheApi.save(CUSTOM_BG_CACHE_NAME, CUSTOM_BG_CACHE_NAME, blob);
onClick(slug);
})();
}, [fullMedia, onClick, slug]);
useEffect(() => {
if (fullMedia) {
handleSelect();
}
}, [fullMedia, handleSelect]);
const handleClick = useCallback(() => {
if (fullMedia) {
handleSelect();
} else {
setIsDownloadAllowed((isAllowed) => !isAllowed);
}
}, [fullMedia, handleSelect]);
const className = buildClassName(
'WallpaperTile',
isSelected && 'selected',
);
return (
<div className={className} onClick={handleClick}>
<div className="media-inner">
{shouldRenderThumb && (
<img
src={thumbDataUri}
className="thumbnail"
alt=""
/>
)}
{shouldRenderFullMedia && (
<img
src={previewBlobUrl || localBlobUrl}
className={`full-media ${transitionClassNames}`}
alt=""
/>
)}
{shouldRenderSpinner && (
<div className={buildClassName('spinner-container', spinnerClassNames)}>
<ProgressSpinner progress={downloadProgress} onClick={handleClick} />
</div>
)}
</div>
</div>
);
};
export default memo(WallpaperTile);