1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

made simple replacement for flow hero slider

This commit is contained in:
Fedor Katurov 2020-11-05 18:06:07 +07:00
parent 9ea5b8ae8f
commit 558fbc703a
2 changed files with 43 additions and 67 deletions

View file

@ -7,111 +7,70 @@ import { getURL } from '~/utils/dom';
import { withRouter, RouteComponentProps } from 'react-router';
import { URLS, PRESETS } from '~/constants/urls';
import { Icon } from '~/components/input/Icon';
import { INode } from "~/redux/types";
type IProps = RouteComponentProps & {
heroes: IFlowState['heroes'];
};
const FlowHeroUnconnected: FC<IProps> = ({ heroes, history }) => {
const [limit, setLimit] = useState(Math.min(heroes.length, 6));
const preset = useMemo(() => (window.innerWidth <= 768 ? PRESETS.cover : PRESETS.small_hero), []);
const [limit, setLimit] = useState(6);
const [current, setCurrent] = useState(0);
const [loaded, setLoaded] = useState([]);
const [loaded, setLoaded] = useState<Partial<INode>[]>([]);
const timer = useRef(null);
const onLoad = useCallback(id => () => setLoaded([...loaded, id]), [setLoaded, loaded]);
const onNext = useCallback(() => {
clearTimeout(timer.current);
const onLoad = useCallback((i: number) => {
setLoaded([...loaded, heroes[i]])
}, [heroes, loaded, setLoaded])
if (loaded.length <= 1) return;
const index = loaded.findIndex(el => el === current);
setCurrent(index > loaded.length - 2 ? loaded[0] : loaded[index + 1]);
}, [loaded, current, setCurrent, timer]);
const onNextPress = useCallback(() => {
setLimit(Math.min(heroes.length, limit + 1));
onNext();
}, [onNext, heroes, limit, setLimit]);
const onPrevious = useCallback(() => {
clearTimeout(timer.current);
if (loaded.length <= 1) return;
const index = loaded.findIndex(el => el === current);
setCurrent(index > 0 ? loaded[index - 1] : loaded[loaded.length - 1]);
}, [loaded, current, setCurrent, timer]);
useEffect(() => {
timer.current = setTimeout(onNext, 5000);
}, [current, onNext]);
useEffect(() => {
if (current === 0 && loaded.length > 0) setCurrent(loaded[0]);
}, [loaded]);
useEffect(() => {
setLimit(limit > 0 ? Math.min(heroes.length, limit) : heroes.length);
}, [heroes, limit]);
const stopSliding = useCallback(() => {
clearTimeout(timer.current);
timer.current = setTimeout(onNext, 5000);
}, [timer, onNext]);
const onClick = useCallback(() => {
if (!current) return;
history.push(URLS.NODE_URL(current));
}, [current]);
const items = Math.min(heroes.length, limit)
const title = useMemo(() => {
if (loaded.length === 0) return null;
const item = heroes.find(hero => hero.id === current);
if (!item || !item.title) return null;
return item.title;
return loaded[current]?.title || '';
}, [loaded, current, heroes]);
const preset = useMemo(() => (window.innerWidth <= 768 ? PRESETS.cover : PRESETS.small_hero), []);
const onNext = useCallback(() => setCurrent(current < items - 1 ? current + 1 : 0), [current, items])
const onPrev = useCallback(() => setCurrent(current > 0 ? current - 1 : items - 1), [current, items])
return (
<div className={styles.wrap} onMouseOver={stopSliding} onFocus={stopSliding}>
{loaded && loaded.length > 0 && (
<div className={styles.wrap}>
<div className={styles.loaders}>
{
heroes.slice(0, items).map((hero, i) => (
<img src={getURL({ url: hero.thumbnail }, preset)} key={hero.id} onLoad={() => onLoad(i)} />
))
}
</div>
{loaded.length > 0 && (
<div className={styles.info}>
<div className={styles.title_wrap}>{title}</div>
<div className={styles.buttons}>
<div className={styles.button} onClick={onPrevious}>
<div className={styles.button} onClick={onPrev}>
<Icon icon="left" />
</div>
<div className={styles.button} onClick={onNextPress}>
<div className={styles.button} onClick={onNext}>
<Icon icon="right" />
</div>
</div>
</div>
)}
{heroes.slice(0, limit).map(hero => (
{loaded.length > 0 && loaded.slice(0, limit).map((hero, index) => (
<div
className={classNames(styles.hero, {
[styles.is_visible]: loaded.includes(hero.id),
[styles.is_active]: current === hero.id,
[styles.is_visible]: true,
[styles.is_active]: current === index,
})}
style={{
backgroundImage: `url("${getURL({ url: hero.thumbnail }, preset)}")`,
}}
key={hero.id}
onClick={onClick}
>
<img
src={getURL({ url: hero.thumbnail }, preset)}
alt={hero.thumbnail}
onLoad={onLoad(hero.id)}
/>
</div>
))}

View file

@ -145,3 +145,20 @@
}
}
}
// new
.loaders {
position: absolute;
top: 0;
left: 0;
opacity: 0;
pointer-events: none;
touch-action: none;
img {
position: absolute;
left: 0;
top: 0;
}
}