import React, { FC, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import styles from './styles.module.scss'; import classNames from 'classnames'; import { INode } from '~/types'; import { PRESETS, URLS } from '~/constants/urls'; import { RouteComponentProps } from 'react-router'; import { getURL, getURLFromString } from '~/utils/dom'; import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString'; import { Square } from '~/components/common/Square'; import { useGotoNode } from '~/hooks/node/useGotoNode'; import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad'; type IProps = { item: Partial; }; type CellSize = 'small' | 'medium' | 'large'; const getTitleLetters = (title?: string): string => { const words = (title && title.split(' ')) || []; if (!words.length) return ''; return words.length > 1 ? words .slice(0, 2) .map(word => word[0]) .join('') .toUpperCase() : words[0].substr(0, 2).toUpperCase(); }; const NodeRelatedItem: FC = memo(({ item }) => { const onClick = useGotoNode(item.id); const [is_loaded, setIsLoaded] = useState(false); const [width, setWidth] = useState(0); const ref = useRef(null); const thumb = useMemo( () => (item.thumbnail ? getURL({ url: item.thumbnail }, PRESETS.avatar) : ''), [item] ); const background = useColorGradientFromString(!thumb ? item.title : ''); useEffect(() => { if (!ref.current) return; const cb = () => setWidth(ref.current!.getBoundingClientRect().width); window.addEventListener('resize', cb); cb(); return () => window.removeEventListener('resize', cb); }, []); const size = useMemo(() => { if (width > 90) return 'large'; if (width > 76) return 'medium'; return 'small'; }, [width]); const image = useMemo(() => getURL({ url: item.thumbnail }, PRESETS.avatar), [item.thumbnail]); return (
{item.thumbnail && ( )} {!item.thumbnail && size === 'small' && (
{getTitleLetters(item.title)}
)} {!item.thumbnail && size !== 'small' && (
{item.title}
)} setIsLoaded(true)} />
); }); export { NodeRelatedItem };