1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-25 12:56:41 +07:00

notifications: for nodes

This commit is contained in:
Fedor Katurov 2023-03-16 16:37:43 +06:00
parent 14bf5be65f
commit d9544e917b
13 changed files with 156 additions and 27 deletions

View file

@ -1,121 +0,0 @@
import { FC, memo, useEffect, useMemo, useRef, useState } from 'react';
import classNames from 'classnames';
import { ImageWithSSRLoad } from '~/components/common/ImageWithSSRLoad';
import { Square } from '~/components/common/Square';
import { Icon } from '~/components/input/Icon';
import { imagePresets } from '~/constants/urls';
import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString';
import { useGotoNode } from '~/hooks/node/useGotoNode';
import { INode } from '~/types';
import { getURL, getURLFromString } from '~/utils/dom';
import styles from './styles.module.scss';
type IProps = {
item: Partial<INode>;
};
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<IProps> = memo(({ item }) => {
const onClick = useGotoNode(item.id);
const [is_loaded, setIsLoaded] = useState(false);
const [width, setWidth] = useState(0);
const ref = useRef<HTMLDivElement>(null);
const thumb = useMemo(
() =>
item.thumbnail
? getURL({ url: item.thumbnail }, imagePresets.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<CellSize>(() => {
if (width > 90) return 'large';
if (width > 76) return 'medium';
return 'small';
}, [width]);
const image = useMemo(
() => getURL({ url: item.thumbnail }, imagePresets.avatar),
[item.thumbnail],
);
return (
<div
className={classNames(styles.item, styles[size], {
[styles.is_loaded]: is_loaded,
})}
key={item.id}
onClick={onClick}
ref={ref}
>
{item.thumbnail && (
<Square
image={getURLFromString(item.thumbnail, 'avatar')}
onClick={onClick}
className={classNames(styles.thumb, {
[styles.is_loaded]: is_loaded,
})}
>
{!item.is_promoted && (
<div className={styles.suffix}>
<Icon icon="lab" size={12} />
</div>
)}
</Square>
)}
{!item.thumbnail && size === 'small' && (
<div className={styles.letters} style={{ background }}>
{getTitleLetters(item.title)}
</div>
)}
{!item.thumbnail && size !== 'small' && (
<div className={styles.title} style={{ background }}>
{item.title}
</div>
)}
<ImageWithSSRLoad
src={image}
alt="loader"
onLoad={() => setIsLoaded(true)}
/>
</div>
);
});
export { NodeRelatedItem };