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

node cover display

This commit is contained in:
Fedor Katurov 2019-10-22 15:49:04 +07:00
parent c8593b7e7a
commit ad0b9e6a28
9 changed files with 94 additions and 7 deletions

View file

@ -1,4 +1,7 @@
.blur {
filter: blur(0);
transition: filter 0.25s;
max-height: 100vh;
width: 100vw;
overflow: visible auto;
}

View file

@ -0,0 +1,25 @@
import React, { FC } from 'react';
import * as styles from './styles.scss';
import { createPortal } from 'react-dom';
import { selectNode } from '~/redux/node/selectors';
import { connect } from 'react-redux';
import pick from 'ramda/es/pick';
import { getURL } from '~/utils/dom';
const mapStateToProps = state => pick(['current_cover_image'], selectNode(state));
type IProps = ReturnType<typeof mapStateToProps> & {};
const PageCoverUnconnected: FC<IProps> = ({ current_cover_image }) =>
current_cover_image
? createPortal(
<div
className={styles.wrap}
style={{ backgroundImage: `url("${getURL(current_cover_image)}")` }}
/>,
document.body
)
: null;
const PageCover = connect(mapStateToProps)(PageCoverUnconnected);
export { PageCover };

View file

@ -0,0 +1,30 @@
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.wrap {
position: absolute;
top: 0;
left: 0;
z-index: -1;
background: 50% 50% no-repeat;
background-size: cover;
width: 100%;
height: 100%;
animation: fadeIn 2s;
&::after {
content: ' ';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url(~/sprites/dots.svg) rgba(0, 0, 0, 0.5);
}
}

View file

@ -14,18 +14,22 @@ import { URLS } from '~/constants/urls';
import { Modal } from '~/containers/dialogs/Modal';
import { selectModal } from '~/redux/modal/selectors';
import { BlurWrapper } from '~/components/containers/BlurWrapper';
import { PageCover } from '~/components/containers/PageCover';
import { NodeLayout } from './node/NodeLayout';
import { BottomContainer } from '~/containers/main/BottomContainer';
const mapStateToProps = selectModal;
const mapStateToProps = state => ({
modal: selectModal(state),
});
const mapDispatchToProps = {};
type IProps = typeof mapDispatchToProps & ReturnType<typeof mapStateToProps> & {};
const Component: FC<IProps> = ({ is_shown }) => (
const Component: FC<IProps> = ({ modal: { is_shown } }) => (
<ConnectedRouter history={history}>
<div>
<BlurWrapper is_blurred={is_shown}>
<PageCover />
<MainLayout>
<Modal />
<Sprites />

View file

@ -26,6 +26,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = {
nodeLoadNode: NODE_ACTIONS.nodeLoadNode,
nodeUpdateTags: NODE_ACTIONS.nodeUpdateTags,
nodeSetCoverImage: NODE_ACTIONS.nodeSetCoverImage,
nodeEdit: NODE_ACTIONS.nodeEdit,
nodeLike: NODE_ACTIONS.nodeLike,
};
@ -38,13 +39,14 @@ const NodeLayoutUnconnected: FC<IProps> = ({
match: {
params: { id },
},
node: { is_loading, is_loading_comments, comments = [], current: node },
node: { is_loading, is_loading_comments, comments = [], current: node, current_cover_image },
user,
user: { is_user, role },
user: { is_user },
nodeLoadNode,
nodeUpdateTags,
nodeEdit,
nodeLike,
nodeSetCoverImage,
}) => {
const [layout, setLayout] = useState({});
@ -71,6 +73,12 @@ const NodeLayoutUnconnected: FC<IProps> = ({
const onEdit = useCallback(() => nodeEdit(node.id), [nodeEdit, node]);
const onLike = useCallback(() => nodeLike(node.id), [nodeLike, node]);
useEffect(() => {
if (!node.cover) return;
nodeSetCoverImage(node.cover);
return () => nodeSetCoverImage(null);
}, [nodeSetCoverImage, node.cover]);
return (
<Card className={styles.node} seamless>
{block && createElement(block, { node, is_loading, updateLayout, layout })}

View file

@ -1,4 +1,4 @@
import { INode, IValidationErrors, IComment, ITag } from '../types';
import { INode, IValidationErrors, IComment, ITag, IFile } from '../types';
import { NODE_ACTIONS, NODE_TYPES } from './constants';
import { INodeState } from './reducer';
@ -84,3 +84,8 @@ export const nodeSetEditor = (editor: INode) => ({
type: NODE_ACTIONS.SET_EDITOR,
editor,
});
export const nodeSetCoverImage = (current_cover_image: IFile) => ({
type: NODE_ACTIONS.SET_COVER_IMAGE,
current_cover_image,
});

View file

@ -35,6 +35,7 @@ export const NODE_ACTIONS = {
UPDATE_TAGS: `${prefix}UPDATE_TAGS`,
SET_TAGS: `${prefix}SET_TAGS`,
SET_COVER_IMAGE: `${prefix}SET_COVER_IMAGE`,
};
export const EMPTY_NODE: INode = {
@ -99,8 +100,10 @@ export const NODE_EDITORS = {
};
export const NODE_PANEL_COMPONENTS = {
[NODE_TYPES.TEXT]: [EditorUploadCoverButton],
[NODE_TYPES.VIDEO]: [EditorUploadCoverButton],
[NODE_TYPES.IMAGE]: [EditorImageUploadButton, EditorUploadCoverButton],
[NODE_TYPES.AUDIO]: [EditorAudioUploadButton, EditorImageUploadButton],
[NODE_TYPES.AUDIO]: [EditorAudioUploadButton, EditorImageUploadButton, EditorUploadCoverButton],
};
export const NODE_EDITOR_DATA: Record<

View file

@ -10,6 +10,7 @@ import {
nodeSetCommentData,
nodeSetTags,
nodeSetEditor,
nodeSetCoverImage,
} from './actions';
import { INodeState } from './reducer';
@ -46,6 +47,11 @@ const setTags = (state: INodeState, { tags }: ReturnType<typeof nodeSetTags>) =>
const setEditor = (state: INodeState, { editor }: ReturnType<typeof nodeSetEditor>) =>
assocPath(['editor'], editor, state);
const setCoverImage = (
state: INodeState,
{ current_cover_image }: ReturnType<typeof nodeSetCoverImage>
) => assocPath(['current_cover_image'], current_cover_image, state);
export const NODE_HANDLERS = {
[NODE_ACTIONS.SET_SAVE_ERRORS]: setSaveErrors,
[NODE_ACTIONS.SET_LOADING]: setLoading,
@ -56,4 +62,5 @@ export const NODE_HANDLERS = {
[NODE_ACTIONS.SET_COMMENT_DATA]: setCommentData,
[NODE_ACTIONS.SET_TAGS]: setTags,
[NODE_ACTIONS.SET_EDITOR]: setEditor,
[NODE_ACTIONS.SET_COVER_IMAGE]: setCoverImage,
};

View file

@ -1,5 +1,5 @@
import { createReducer } from '~/utils/reducer';
import { INode, IComment } from '../types';
import { INode, IComment, IFile } from '../types';
import { EMPTY_NODE, EMPTY_COMMENT } from './constants';
import { NODE_HANDLERS } from './handlers';
@ -8,6 +8,7 @@ export type INodeState = Readonly<{
current: INode;
comments: IComment[];
comment_data: Record<number, IComment>;
current_cover_image: IFile;
error: string;
errors: Record<string, string>;
@ -27,6 +28,7 @@ const INITIAL_STATE: INodeState = {
current: { ...EMPTY_NODE },
comment_data: { 0: { ...EMPTY_COMMENT } },
comments: [],
current_cover_image: null,
is_loading: false,
is_loading_comments: false,