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

removed search reducer completely

This commit is contained in:
Fedor Katurov 2022-01-04 15:51:44 +07:00
parent 38eedab3c2
commit b82ccfb786
22 changed files with 146 additions and 570 deletions

View file

@ -1,108 +0,0 @@
import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { IFlowState } from '~/redux/flow/reducer';
import classNames from 'classnames';
import styles from './styles.module.scss';
import { getURL } from '~/utils/dom';
import { RouteComponentProps, useHistory, withRouter } from 'react-router';
import { PRESETS, URLS } 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 }) => {
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<Partial<INode>[]>([]);
const timer = useRef<any>(null);
const history = useHistory();
const onLoad = useCallback(
(i: number) => {
setLoaded([...loaded, heroes[i]]);
},
[heroes, loaded, setLoaded]
);
const items = Math.min(heroes.length, limit);
const title = useMemo(() => {
return loaded[current]?.title || '';
}, [loaded, current]);
const onNext = useCallback(() => {
if (heroes.length > limit) setLimit(limit + 1);
setCurrent(current < items - 1 ? current + 1 : 0);
}, [current, items, limit, heroes.length]);
const onPrev = useCallback(() => setCurrent(current > 0 ? current - 1 : items - 1), [
current,
items,
]);
const goToNode = useCallback(() => {
history.push(URLS.NODE_URL(loaded[current].id));
}, [current, history, loaded]);
useEffect(() => {
timer.current = setTimeout(onNext, 5000);
return () => clearTimeout(timer.current);
}, [current, onNext]);
useEffect(() => {
if (loaded.length === 1) onNext();
}, [loaded, onNext]);
return (
<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)}
alt=""
/>
))}
</div>
{loaded.length > 0 && (
<div className={styles.info}>
<div className={styles.title_wrap}>{title}</div>
<div className={styles.buttons}>
<div className={styles.button} onClick={onPrev}>
<Icon icon="left" />
</div>
<div className={styles.button} onClick={onNext}>
<Icon icon="right" />
</div>
</div>
</div>
)}
{loaded.slice(0, limit).map((hero, index) => (
<div
className={classNames(styles.hero, {
[styles.is_visible]: true,
[styles.is_active]: current === index,
})}
style={{
backgroundImage: `url("${getURL({ url: hero.thumbnail }, preset)}")`,
}}
key={hero.id}
onClick={goToNode}
>
<img src={getURL({ url: hero.thumbnail }, preset)} alt={hero.thumbnail} />
</div>
))}
</div>
);
};
const FlowHero = withRouter(FlowHeroUnconnected);
export { FlowHero };

View file

@ -1,162 +0,0 @@
@import "src/styles/variables";
.wrap {
width: 100%;
height: 100%;
position: relative;
background: $content_bg;
border-radius: $cell_radius;
overflow: hidden;
user-select: none;
&::after {
content: ' ';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('../../../sprites/stripes.svg') rgba(0, 0, 0, 0.3);
z-index: 4;
pointer-events: none;
box-shadow: inset transparentize($color: white, $amount: 0.85) 0 1px;
touch-action: none;
border-radius: $radius;
}
&::before {
content: ' ';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
182deg,
transparentize($cell_shade, 1) 50%,
transparentize($cell_shade, 0) 95%
);
z-index: 4;
pointer-events: none;
touch-action: none;
}
}
.hero {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 150%;
display: none;
transition: opacity 2s, transform linear 5s 2s;
background: 50% 50% no-repeat;
background-size: cover;
border-radius: $cell_radius;
z-index: 2;
opacity: 0;
cursor: pointer;
transform: translate(0, 0);
img {
width: 0;
height: 0;
opacity: 0;
pointer-events: none;
touch-action: none;
}
&.is_visible {
display: block;
}
&.is_active {
opacity: 1;
z-index: 3;
will-change: transform;
// animation: rise 5s forwards;
transform: translate(0, -10%);
transition: opacity 2s, transform linear 5s;
}
}
.info {
display: flex;
position: absolute;
bottom: 0;
right: 0;
width: 100%;
padding: $gap;
box-sizing: border-box;
z-index: 5;
flex-direction: row;
align-items: flex-end;
pointer-events: none;
touch-action: none;
}
.title_wrap {
flex: 1;
white-space: nowrap;
display: flex;
margin-right: $gap;
overflow: hidden;
font: $font_hero_title;
text-transform: uppercase;
text-overflow: ellipsis;
line-height: 1.2em;
@include tablet {
white-space: initial;
word-wrap: break-word;
font: $font_32_bold;
max-height: 3.6em;
}
@include phone {
white-space: initial;
word-wrap: break-word;
font: $font_24_bold;
max-height: 3.6em;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
height: 48px;
flex-direction: row;
width: 96px;
border-radius: $radius;
pointer-events: all;
touch-action: auto;
.button {
cursor: pointer;
flex: 0 0 48px;
display: flex;
align-items: center;
justify-content: center;
svg {
width: 40px;
height: 40px;
}
}
}
.loaders {
position: absolute;
top: 0;
left: 0;
opacity: 0;
pointer-events: none;
touch-action: none;
img {
position: absolute;
left: 0;
top: 0;
}
}

View file

@ -1,11 +1,11 @@
import React, { FC } from 'react';
import { IFlowState } from '~/redux/flow/reducer';
import { FlowRecentItem } from '../FlowRecentItem';
import styles from './styles.module.scss';
import { IFlowNode } from '~/redux/types';
interface IProps {
recent: IFlowState['recent'];
updated: IFlowState['updated'];
recent: IFlowNode[];
updated: IFlowNode[];
}
const FlowRecent: FC<IProps> = ({ recent, updated }) => {

View file

@ -1,37 +1,18 @@
import React, { FC, useCallback } from 'react';
import React, { FC } from 'react';
import styles from './styles.module.scss';
import { LoaderCircle } from '~/components/input/LoaderCircle';
import { FlowRecentItem } from '../FlowRecentItem';
import { Icon } from '~/components/input/Icon';
import { INode } from '~/redux/types';
import { InfiniteScroll } from '~/components/containers/InfiniteScroll';
interface IProps {
isLoading: boolean;
results: INode[];
hasMore: boolean;
onLoadMore: () => void;
}
const FlowSearchResults: FC<IProps> = ({ results, isLoading, onLoadMore }) => {
const onScroll = useCallback(
event => {
const el = event.target;
const bottom = el.scrollHeight - el.scrollTop - el.clientHeight;
if (bottom > 100) return;
onLoadMore();
},
[onLoadMore]
);
if (isLoading) {
return (
<div className={styles.loading}>
<LoaderCircle size={64} />
</div>
);
}
const FlowSearchResults: FC<IProps> = ({ results, isLoading, onLoadMore, hasMore }) => {
if (!results.length) {
return (
<div className={styles.loading}>
@ -42,10 +23,12 @@ const FlowSearchResults: FC<IProps> = ({ results, isLoading, onLoadMore }) => {
}
return (
<div className={styles.wrap} onScroll={onScroll}>
{results.map(node => (
<FlowRecentItem node={node} key={node.id} />
))}
<div className={styles.wrap}>
<InfiniteScroll hasMore={hasMore} loadMore={onLoadMore}>
{results.map(node => (
<FlowRecentItem node={node} key={node.id} />
))}
</InfiniteScroll>
</div>
);
};

View file

@ -7,18 +7,18 @@ import styles from './styles.module.scss';
import SwiperCore, { Autoplay, EffectFade, Lazy, Navigation } from 'swiper';
import { Icon } from '~/components/input/Icon';
import { IFlowState } from '~/redux/flow/reducer';
import { getURLFromString } from '~/utils/dom';
import { PRESETS, URLS } from '~/constants/urls';
import SwiperClass from 'swiper/types/swiper-class';
import { LoaderCircle } from '~/components/input/LoaderCircle';
import { useHistory } from 'react-router';
import classNames from 'classnames';
import { IFlowNode } from '~/redux/types';
SwiperCore.use([EffectFade, Lazy, Autoplay, Navigation]);
interface Props {
heroes: IFlowState['heroes'];
heroes: IFlowNode[];
}
export const FlowSwiperHero: FC<Props> = ({ heroes }) => {