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

added working tiny-slider!

This commit is contained in:
Fedor Katurov 2020-10-26 19:14:41 +07:00
parent fefec524db
commit 531bd3626a
7 changed files with 122 additions and 57 deletions

View file

@ -0,0 +1,46 @@
import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import styles from './styles.module.scss';
import ResizeSensor from 'resize-sensor';
const FullWidth: FC = ({ children }) => {
const sample = useRef<HTMLDivElement>(null);
const [clientWidth, setClientWidth] = useState(document.documentElement.clientWidth);
const style = useMemo(() => {
if (!sample.current) return { display: 'none' };
const { width } = sample.current.getBoundingClientRect();
const { clientWidth } = document.documentElement;
return {
width: clientWidth,
transform: `translate(-${(clientWidth - width) / 2}px, 0)`,
};
}, [sample.current, clientWidth]);
const onResize = useCallback(() => setClientWidth(document.documentElement.clientWidth), []);
useEffect(() => {
if (!sample.current) return;
window.addEventListener('resize', onResize);
new ResizeSensor(document.body, onResize);
return () => {
window.removeEventListener('resize', onResize);
ResizeSensor.detach(document.body, onResize);
};
}, []);
return (
<div className={styles.wrap}>
<div className={styles.slider} style={style}>
{children}
</div>
<div className={styles.sample} ref={sample} />
</div>
);
};
export { FullWidth };

View file

@ -0,0 +1,10 @@
.sample {
width: 100%;
display: block;
background: green;
height: 0;
}
.slider {
max-height: calc(100vh - 125px);
}

View file

@ -1,44 +1,41 @@
import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import React, { FC } from 'react';
import { INodeComponentProps } from '~/redux/node/constants';
import { FullWidth } from '~/components/containers/FullWidth';
import { useNodeImages } from '~/utils/node';
import { getURL } from '~/utils/dom';
import { PRESETS } from '~/constants/urls';
import TinySlider from 'tiny-slider-react';
import styles from './styles.module.scss';
interface IProps {}
const settings = {
nav: false,
buttons: false,
mouseDrag: true,
gutter: 10,
center: true,
lazyload: true,
items: 1,
edgePadding: 150,
loop: true,
arrowKeys: false,
prevButton: false,
nextButton: false,
swipeAngle: 45,
};
const NodeImageTinySlider: FC<IProps> = () => {
const sample = useRef<HTMLDivElement>(null);
const [clientWidth, setClientWidth] = useState(document.documentElement.clientWidth);
const style = useMemo(() => {
if (!sample.current) return { display: 'none' };
const { width } = sample.current.getBoundingClientRect();
const { clientWidth } = document.documentElement;
return {
// width: clientWidth,
// transform: `translate(-${(clientWidth - width) / 2}px, 0)`,
};
}, [sample.current, clientWidth]);
const onResize = useCallback(() => setClientWidth(document.documentElement.clientWidth), []);
useEffect(() => {
window.addEventListener('resize', onResize);
document.body.addEventListener('overflow', onResize);
document.body.addEventListener('overflowchanged', console.log);
document.body.addEventListener('resize', console.log);
return () => {
window.removeEventListener('resize', onResize);
window.removeEventListener('overflow', onResize);
};
}, []);
const NodeImageTinySlider: FC<INodeComponentProps> = ({ node }) => {
const images = useNodeImages(node);
return (
<div className={styles.wrap}>
<div className={styles.slider} style={style} />
<div className={styles.sample} ref={sample} />
</div>
<FullWidth>
<div className={styles.slider}>
<TinySlider settings={settings}>
{images.map(image => (
<img src={getURL(image, PRESETS['1600'])} key={image.url} />
))}
</TinySlider>
</div>
</FullWidth>
);
};

View file

@ -1,22 +1,5 @@
.wrap {
background: $red;
}
.sample {
width: 100%;
display: block;
height: 24px;
background: green;
}
.slider {
background: blue;
height: 20px;
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
box-sizing: border-box;
img {
max-height: calc(100vh - 140px);
}
}

View file

@ -1,8 +1,10 @@
import { USER_ROLES } from '~/redux/auth/constants';
import { INode, IComment, ICommentGroup } from '~/redux/types';
import { INode, IComment, ICommentGroup, IFile } from '~/redux/types';
import { IUser } from '~/redux/auth/types';
import path from 'ramda/es/path';
import { NODE_TYPES } from '~/redux/node/constants';
import { useMemo } from 'react';
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
export const canEditNode = (node: Partial<INode>, user: Partial<IUser>): boolean =>
path(['role'], user) === USER_ROLES.ADMIN ||
@ -19,3 +21,11 @@ export const canStarNode = (node: Partial<INode>, user: Partial<IUser>): boolean
node.type === NODE_TYPES.IMAGE &&
path(['role'], user) &&
path(['role'], user) === USER_ROLES.ADMIN;
export const useNodeImages = (node: INode): IFile[] => {
return useMemo(
() =>
(node && node.files && node.files.filter(({ type }) => type === UPLOAD_TYPES.IMAGE)) || [],
[node.files]
);
};