import type { FC } from '../../../lib/teact/teact'; import React, { memo, useCallback, useEffect, useState, useRef, } from '../../../lib/teact/teact'; import type { ApiWallpaper } from '../../../api/types'; import type { ThemeKey } from '../../../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 buildClassName from '../../../util/buildClassName'; import useMedia from '../../../hooks/useMedia'; import useMediaWithLoadProgress from '../../../hooks/useMediaWithLoadProgress'; import useShowTransition from '../../../hooks/useShowTransition'; import usePrevious from '../../../hooks/usePrevious'; import useCanvasBlur from '../../../hooks/useCanvasBlur'; import ProgressSpinner from '../../ui/ProgressSpinner'; import './WallpaperTile.scss'; type OwnProps = { wallpaper: ApiWallpaper; theme: ThemeKey; isSelected: boolean; onClick: (slug: string) => void; }; const WallpaperTile: FC = ({ wallpaper, theme, isSelected, onClick, }) => { const { slug, document } = wallpaper; const localMediaHash = `wallpaper${document.id!}`; const localBlobUrl = document.previewBlobUrl; const previewBlobUrl = useMedia(`${localMediaHash}?size=m`); const thumbRef = useCanvasBlur(document.thumbnail?.dataUri, Boolean(previewBlobUrl), true); const { transitionClassNames } = useShowTransition( Boolean(previewBlobUrl || localBlobUrl), undefined, undefined, 'slow', ); const [isLoadAllowed, setIsLoadAllowed] = useState(false); const { mediaData: fullMedia, loadProgress, } = useMediaWithLoadProgress(localMediaHash, !isLoadAllowed); const wasLoadDisabled = usePrevious(isLoadAllowed) === false; const { shouldRender: shouldRenderSpinner, transitionClassNames: spinnerClassNames } = useShowTransition( (isLoadAllowed && !fullMedia) || slug === UPLOADING_WALLPAPER_SLUG, undefined, wasLoadDisabled, 'slow', ); // To prevent triggering of the effect for useCallback const cacheKeyRef = useRef(); cacheKeyRef.current = theme; const handleSelect = useCallback(() => { (async () => { const blob = await fetchBlob(fullMedia!); await cacheApi.save(CUSTOM_BG_CACHE_NAME, cacheKeyRef.current!, blob); onClick(slug); })(); }, [fullMedia, onClick, slug]); useEffect(() => { if (fullMedia) { handleSelect(); } }, [fullMedia, handleSelect]); const handleClick = useCallback(() => { if (fullMedia) { handleSelect(); } else { setIsLoadAllowed((isAllowed) => !isAllowed); } }, [fullMedia, handleSelect]); const className = buildClassName( 'WallpaperTile', isSelected && 'selected', ); return (
{shouldRenderSpinner && (
)}
); }; export default memo(WallpaperTile);