mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
removed node reducer
This commit is contained in:
parent
168ba8cc04
commit
8d2b56cafc
14 changed files with 62 additions and 208 deletions
|
@ -1,27 +0,0 @@
|
||||||
import React, { FC, memo } from 'react';
|
|
||||||
import styles from './styles.module.scss';
|
|
||||||
import { createPortal } from 'react-dom';
|
|
||||||
import { selectNode } from '~/redux/node/selectors';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { pick } from 'ramda';
|
|
||||||
import { getURL } from '~/utils/dom';
|
|
||||||
import { PRESETS } from '~/constants/urls';
|
|
||||||
|
|
||||||
const mapStateToProps = state => pick(['current_cover_image'], selectNode(state));
|
|
||||||
|
|
||||||
type IProps = ReturnType<typeof mapStateToProps> & {};
|
|
||||||
|
|
||||||
const PageCoverUnconnected: FC<IProps> = memo(({ current_cover_image }) =>
|
|
||||||
current_cover_image
|
|
||||||
? createPortal(
|
|
||||||
<div
|
|
||||||
className={styles.wrap}
|
|
||||||
style={{ backgroundImage: `url("${getURL(current_cover_image, PRESETS.cover)}")` }}
|
|
||||||
/>,
|
|
||||||
document.body
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
);
|
|
||||||
|
|
||||||
const PageCover = connect(mapStateToProps)(PageCoverUnconnected);
|
|
||||||
export { PageCover };
|
|
39
src/components/containers/PageCoverProvider/index.tsx
Normal file
39
src/components/containers/PageCoverProvider/index.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import React, { createContext, FC, memo, useContext, useState } from 'react';
|
||||||
|
import styles from './styles.module.scss';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
|
import { getURL } from '~/utils/dom';
|
||||||
|
import { PRESETS } from '~/constants/urls';
|
||||||
|
import { IFile } from '~/redux/types';
|
||||||
|
|
||||||
|
interface CoverContextValue {
|
||||||
|
cover: IFile | null;
|
||||||
|
setCover: (cover: IFile | null) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CoverContext = createContext<CoverContextValue>({
|
||||||
|
cover: null,
|
||||||
|
setCover: () => {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const PageCoverProvider: FC = ({ children }) => {
|
||||||
|
const [cover, setCover] = useState<IFile | null>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CoverContext.Provider value={{ cover, setCover }}>
|
||||||
|
{!!cover &&
|
||||||
|
createPortal(
|
||||||
|
<div
|
||||||
|
className={styles.wrap}
|
||||||
|
style={{ backgroundImage: `url("${getURL(cover, PRESETS.cover)}")` }}
|
||||||
|
/>,
|
||||||
|
document.body
|
||||||
|
)}
|
||||||
|
|
||||||
|
{children}
|
||||||
|
</CoverContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const usePageCoverContext = () => useContext(CoverContext);
|
||||||
|
|
||||||
|
export { PageCoverProvider, usePageCoverContext };
|
12
src/components/containers/PageCoverProvider/usePageCover.ts
Normal file
12
src/components/containers/PageCoverProvider/usePageCover.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { IFile } from '~/redux/types';
|
||||||
|
import { usePageCoverContext } from '~/components/containers/PageCoverProvider/index';
|
||||||
|
|
||||||
|
export const usePageCover = (cover?: IFile) => {
|
||||||
|
const { setCover } = usePageCoverContext();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCover(cover || null);
|
||||||
|
return () => setCover(null);
|
||||||
|
}, [setCover, cover]);
|
||||||
|
};
|
|
@ -4,7 +4,7 @@ import { history } from '~/redux/store';
|
||||||
import { MainLayout } from '~/containers/main/MainLayout';
|
import { MainLayout } from '~/containers/main/MainLayout';
|
||||||
import { Sprites } from '~/sprites/Sprites';
|
import { Sprites } from '~/sprites/Sprites';
|
||||||
import { Modal } from '~/containers/dialogs/Modal';
|
import { Modal } from '~/containers/dialogs/Modal';
|
||||||
import { PageCover } from '~/components/containers/PageCover';
|
import { PageCoverProvider } from '~/components/containers/PageCoverProvider';
|
||||||
import { BottomContainer } from '~/containers/main/BottomContainer';
|
import { BottomContainer } from '~/containers/main/BottomContainer';
|
||||||
import { MainRouter } from '~/containers/main/MainRouter';
|
import { MainRouter } from '~/containers/main/MainRouter';
|
||||||
import { DragDetectorProvider } from '~/hooks/dom/useDragDetector';
|
import { DragDetectorProvider } from '~/hooks/dom/useDragDetector';
|
||||||
|
@ -20,15 +20,15 @@ const App: VFC = () => {
|
||||||
<SWRConfigProvider>
|
<SWRConfigProvider>
|
||||||
<UserContextProvider user={user}>
|
<UserContextProvider user={user}>
|
||||||
<DragDetectorProvider>
|
<DragDetectorProvider>
|
||||||
<PageCover />
|
<PageCoverProvider>
|
||||||
|
<MainLayout>
|
||||||
|
<Modal />
|
||||||
|
<Sprites />
|
||||||
|
|
||||||
<MainLayout>
|
<MainRouter />
|
||||||
<Modal />
|
</MainLayout>
|
||||||
<Sprites />
|
<BottomContainer />
|
||||||
|
</PageCoverProvider>
|
||||||
<MainRouter />
|
|
||||||
</MainLayout>
|
|
||||||
<BottomContainer />
|
|
||||||
</DragDetectorProvider>
|
</DragDetectorProvider>
|
||||||
</UserContextProvider>
|
</UserContextProvider>
|
||||||
</SWRConfigProvider>
|
</SWRConfigProvider>
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
import React, { FC, useEffect, useState } from 'react';
|
|
||||||
import { RouteComponentProps, useRouteMatch, withRouter } from 'react-router';
|
|
||||||
import styles from './styles.module.scss';
|
|
||||||
import { NodeNoComments } from '~/components/node/NodeNoComments';
|
|
||||||
import { Grid } from '~/components/containers/Grid';
|
|
||||||
import * as NODE_ACTIONS from '~/redux/node/actions';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { IUser } from '~/redux/auth/types';
|
|
||||||
import { Group } from '~/components/containers/Group';
|
|
||||||
import { CommentForm } from '~/components/comment/CommentForm';
|
|
||||||
|
|
||||||
const mapStateToProps = () => ({});
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
nodeSetCoverImage: NODE_ACTIONS.nodeSetCoverImage,
|
|
||||||
};
|
|
||||||
|
|
||||||
type IProps = RouteComponentProps & typeof mapDispatchToProps & {};
|
|
||||||
|
|
||||||
const ProfileLayoutUnconnected: FC<IProps> = ({ history, nodeSetCoverImage }) => {
|
|
||||||
const {
|
|
||||||
params: { username },
|
|
||||||
} = useRouteMatch<{ username: string }>();
|
|
||||||
const [user, setUser] = useState<IUser | undefined>(undefined);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (user) setUser(undefined);
|
|
||||||
}, [user, username]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (user && user.id && user.cover) {
|
|
||||||
nodeSetCoverImage(user.cover);
|
|
||||||
return () => {
|
|
||||||
nodeSetCoverImage(undefined);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, [nodeSetCoverImage, user]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Group className={styles.wrap} horizontal>
|
|
||||||
<div className={styles.column} />
|
|
||||||
|
|
||||||
<Grid className={styles.content}>
|
|
||||||
<div className={styles.comments}>
|
|
||||||
<CommentForm nodeId={0} saveComment={async () => console.log()} />
|
|
||||||
<NodeNoComments is_loading={false} />
|
|
||||||
</div>
|
|
||||||
</Grid>
|
|
||||||
</Group>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const ProfileLayout = connect(
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(withRouter(ProfileLayoutUnconnected));
|
|
||||||
|
|
||||||
export { ProfileLayout };
|
|
|
@ -1,29 +0,0 @@
|
||||||
@import "src/styles/variables";
|
|
||||||
|
|
||||||
.wrap {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start !important;
|
|
||||||
justify-content: flex-start !important;
|
|
||||||
flex-direction: row;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
flex: 3;
|
|
||||||
// flex: 0 1 $limited_width;
|
|
||||||
// padding: $gap;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info {
|
|
||||||
}
|
|
||||||
|
|
||||||
.comments {
|
|
||||||
background: $node_bg;
|
|
||||||
border-radius: $radius;
|
|
||||||
padding: $gap;
|
|
||||||
}
|
|
|
@ -1,16 +1,6 @@
|
||||||
import { INode } from '~/redux/types';
|
import { INode } from '~/redux/types';
|
||||||
import { useEffect } from 'react';
|
import { usePageCover } from '~/components/containers/PageCoverProvider/usePageCover';
|
||||||
import { useDispatch } from 'react-redux';
|
|
||||||
import { nodeSetCoverImage } from '~/redux/node/actions';
|
|
||||||
|
|
||||||
export const useNodeCoverImage = (node: INode) => {
|
export const useNodeCoverImage = (node: INode) => {
|
||||||
const dispatch = useDispatch();
|
usePageCover(node.cover);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(nodeSetCoverImage(node.cover));
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
dispatch(nodeSetCoverImage(undefined));
|
|
||||||
};
|
|
||||||
}, [dispatch, node.cover, node.id]);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
import { IFile } from '../types';
|
|
||||||
import { NODE_ACTIONS } from './constants';
|
|
||||||
|
|
||||||
export const nodeSetCoverImage = (current_cover_image?: IFile) => ({
|
|
||||||
type: NODE_ACTIONS.SET_COVER_IMAGE,
|
|
||||||
current_cover_image,
|
|
||||||
});
|
|
|
@ -23,11 +23,6 @@ import { LabDescription } from '~/components/lab/LabDescription';
|
||||||
import { LabVideo } from '~/components/lab/LabVideo';
|
import { LabVideo } from '~/components/lab/LabVideo';
|
||||||
import { LabAudio } from '~/components/lab/LabAudioBlock';
|
import { LabAudio } from '~/components/lab/LabAudioBlock';
|
||||||
|
|
||||||
const prefix = 'NODE.';
|
|
||||||
export const NODE_ACTIONS = {
|
|
||||||
SET_COVER_IMAGE: `${prefix}SET_COVER_IMAGE`,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const EMPTY_NODE: INode = {
|
export const EMPTY_NODE: INode = {
|
||||||
id: 0,
|
id: 0,
|
||||||
user: undefined,
|
user: undefined,
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
import { assocPath } from 'ramda';
|
|
||||||
import { NODE_ACTIONS } from './constants';
|
|
||||||
import { nodeSetCoverImage } from './actions';
|
|
||||||
import { INodeState } from './reducer';
|
|
||||||
|
|
||||||
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_COVER_IMAGE]: setCoverImage,
|
|
||||||
};
|
|
|
@ -1,42 +0,0 @@
|
||||||
import { createReducer } from '~/utils/reducer';
|
|
||||||
import { IComment, IFile, INode } from '../types';
|
|
||||||
import { EMPTY_NODE } from './constants';
|
|
||||||
import { NODE_HANDLERS } from './handlers';
|
|
||||||
|
|
||||||
export type INodeState = Readonly<{
|
|
||||||
editor: INode;
|
|
||||||
current: INode;
|
|
||||||
comments: IComment[];
|
|
||||||
lastSeenCurrent?: string;
|
|
||||||
comment_count: number;
|
|
||||||
current_cover_image?: IFile;
|
|
||||||
|
|
||||||
error: string;
|
|
||||||
errors: Record<string, string>;
|
|
||||||
|
|
||||||
is_loading: boolean;
|
|
||||||
is_loading_comments: boolean;
|
|
||||||
is_sending_comment: boolean;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
const INITIAL_STATE: INodeState = {
|
|
||||||
editor: {
|
|
||||||
...EMPTY_NODE,
|
|
||||||
type: 'image',
|
|
||||||
blocks: [],
|
|
||||||
files: [],
|
|
||||||
},
|
|
||||||
current: { ...EMPTY_NODE },
|
|
||||||
comment_count: 0,
|
|
||||||
comments: [],
|
|
||||||
current_cover_image: undefined,
|
|
||||||
|
|
||||||
is_loading: false,
|
|
||||||
is_loading_comments: false,
|
|
||||||
is_sending_comment: false,
|
|
||||||
|
|
||||||
error: '',
|
|
||||||
errors: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createReducer(INITIAL_STATE, NODE_HANDLERS);
|
|
|
@ -1,3 +0,0 @@
|
||||||
import { IState } from '../store';
|
|
||||||
|
|
||||||
export const selectNode = (state: IState) => state.node;
|
|
|
@ -11,8 +11,6 @@ import auth from '~/redux/auth';
|
||||||
import authSaga from '~/redux/auth/sagas';
|
import authSaga from '~/redux/auth/sagas';
|
||||||
import { IAuthState } from '~/redux/auth/types';
|
import { IAuthState } from '~/redux/auth/types';
|
||||||
|
|
||||||
import node, { INodeState } from '~/redux/node/reducer';
|
|
||||||
|
|
||||||
import flow, { IFlowState } from '~/redux/flow/reducer';
|
import flow, { IFlowState } from '~/redux/flow/reducer';
|
||||||
import flowSaga from '~/redux/flow/sagas';
|
import flowSaga from '~/redux/flow/sagas';
|
||||||
|
|
||||||
|
@ -65,7 +63,6 @@ export interface IState {
|
||||||
auth: IAuthState;
|
auth: IAuthState;
|
||||||
modal: IModalState;
|
modal: IModalState;
|
||||||
router: RouterState;
|
router: RouterState;
|
||||||
node: INodeState;
|
|
||||||
uploads: IUploadState;
|
uploads: IUploadState;
|
||||||
flow: IFlowState;
|
flow: IFlowState;
|
||||||
player: IPlayerState;
|
player: IPlayerState;
|
||||||
|
@ -91,7 +88,6 @@ export const store = createStore(
|
||||||
modal,
|
modal,
|
||||||
boris,
|
boris,
|
||||||
router: connectRouter(history),
|
router: connectRouter(history),
|
||||||
node,
|
|
||||||
uploads,
|
uploads,
|
||||||
flow: persistReducer(flowPersistConfig, flow),
|
flow: persistReducer(flowPersistConfig, flow),
|
||||||
player: persistReducer(playerPersistConfig, player),
|
player: persistReducer(playerPersistConfig, player),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue