mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 12:56:41 +07:00
refactored flow layout
This commit is contained in:
parent
756c82c8aa
commit
02885b89d5
4 changed files with 150 additions and 78 deletions
|
@ -1,14 +1,11 @@
|
||||||
import React, { FC } from 'react';
|
import React, { FC } from 'react';
|
||||||
import { Cell } from '~/components/flow/Cell';
|
import { Cell } from '~/components/flow/Cell';
|
||||||
|
|
||||||
import * as styles from './styles.scss';
|
|
||||||
import { IFlowState } from '~/redux/flow/reducer';
|
import { IFlowState } from '~/redux/flow/reducer';
|
||||||
import { INode } from '~/redux/types';
|
import { INode } from '~/redux/types';
|
||||||
import { canEditNode } from '~/utils/node';
|
import { canEditNode } from '~/utils/node';
|
||||||
import { IUser } from '~/redux/auth/types';
|
import { IUser } from '~/redux/auth/types';
|
||||||
import { flowSetCellView } from '~/redux/flow/actions';
|
import { flowSetCellView } from '~/redux/flow/actions';
|
||||||
import { FlowHero } from '../FlowHero';
|
|
||||||
import { FlowRecent } from '../FlowRecent';
|
|
||||||
|
|
||||||
type IProps = Partial<IFlowState> & {
|
type IProps = Partial<IFlowState> & {
|
||||||
user: Partial<IUser>;
|
user: Partial<IUser>;
|
||||||
|
@ -16,25 +13,8 @@ type IProps = Partial<IFlowState> & {
|
||||||
onChangeCellView: typeof flowSetCellView;
|
onChangeCellView: typeof flowSetCellView;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FlowGrid: FC<IProps> = ({
|
export const FlowGrid: FC<IProps> = ({ user, nodes, onSelect, onChangeCellView }) => (
|
||||||
user,
|
<>
|
||||||
nodes,
|
|
||||||
heroes,
|
|
||||||
recent,
|
|
||||||
updated,
|
|
||||||
onSelect,
|
|
||||||
onChangeCellView,
|
|
||||||
}) => (
|
|
||||||
<div>
|
|
||||||
<div className={styles.grid_test}>
|
|
||||||
<div className={styles.hero}>
|
|
||||||
<FlowHero heroes={heroes} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.stamp}>
|
|
||||||
<FlowRecent recent={recent} updated={updated} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{nodes.map(node => (
|
{nodes.map(node => (
|
||||||
<Cell
|
<Cell
|
||||||
key={node.id}
|
key={node.id}
|
||||||
|
@ -44,6 +24,5 @@ export const FlowGrid: FC<IProps> = ({
|
||||||
onChangeCellView={onChangeCellView}
|
onChangeCellView={onChangeCellView}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,11 +2,6 @@ $cols: $content_width / $cell;
|
||||||
$stamp_color: $content_bg;
|
$stamp_color: $content_bg;
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
padding: $gap / 2;
|
|
||||||
margin: 0 (-$gap / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid_test {
|
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
@ -73,7 +68,7 @@ $stamp_color: $content_bg;
|
||||||
|
|
||||||
.stamp {
|
.stamp {
|
||||||
@include outer_shadow();
|
@include outer_shadow();
|
||||||
// grid-row: -1 / 3;
|
|
||||||
grid-row-end: span 2;
|
grid-row-end: span 2;
|
||||||
grid-column: -2 / -1;
|
grid-column: -2 / -1;
|
||||||
background: $stamp_color;
|
background: $stamp_color;
|
||||||
|
@ -90,16 +85,13 @@ $stamp_color: $content_bg;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: "";
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: linear-gradient(
|
background: linear-gradient(transparentize($stamp_color, 1), $stamp_color 90%);
|
||||||
transparentize($stamp_color, 1),
|
|
||||||
$stamp_color 90%
|
|
||||||
);
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,37 @@
|
||||||
import React, { FC, useEffect, useCallback } from "react";
|
import React, { FC, useEffect, useCallback } from 'react';
|
||||||
import { connect } from "react-redux";
|
import { connect } from 'react-redux';
|
||||||
import { FlowGrid } from "~/components/flow/FlowGrid";
|
import { FlowGrid } from '~/components/flow/FlowGrid';
|
||||||
import { selectFlow } from "~/redux/flow/selectors";
|
import { selectFlow } from '~/redux/flow/selectors';
|
||||||
import * as NODE_ACTIONS from "~/redux/node/actions";
|
import * as NODE_ACTIONS from '~/redux/node/actions';
|
||||||
import * as FLOW_ACTIONS from "~/redux/flow/actions";
|
import * as FLOW_ACTIONS from '~/redux/flow/actions';
|
||||||
import pick from "ramda/es/pick";
|
import pick from 'ramda/es/pick';
|
||||||
import { selectUser } from "~/redux/auth/selectors";
|
import { selectUser } from '~/redux/auth/selectors';
|
||||||
|
import { FlowHero } from '~/components/flow/FlowHero';
|
||||||
|
import { FlowRecent } from '~/components/flow/FlowRecent';
|
||||||
|
import styles from './styles.scss';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
flow: pick(
|
flow: pick(['nodes', 'heroes', 'recent', 'updated', 'is_loading'], selectFlow(state)),
|
||||||
["nodes", "heroes", "recent", "updated", "is_loading"],
|
user: pick(['role', 'id'], selectUser(state)),
|
||||||
selectFlow(state)
|
|
||||||
),
|
|
||||||
user: pick(["role", "id"], selectUser(state))
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
nodeGotoNode: NODE_ACTIONS.nodeGotoNode,
|
nodeGotoNode: NODE_ACTIONS.nodeGotoNode,
|
||||||
flowSetCellView: FLOW_ACTIONS.flowSetCellView,
|
flowSetCellView: FLOW_ACTIONS.flowSetCellView,
|
||||||
flowGetMore: FLOW_ACTIONS.flowGetMore
|
flowGetMore: FLOW_ACTIONS.flowGetMore,
|
||||||
};
|
};
|
||||||
|
|
||||||
type IProps = ReturnType<typeof mapStateToProps> &
|
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
||||||
typeof mapDispatchToProps & {};
|
|
||||||
|
|
||||||
const FlowLayoutUnconnected: FC<IProps> = ({
|
const FlowLayoutUnconnected: FC<IProps> = ({
|
||||||
flow: { nodes, heroes, recent, updated, is_loading },
|
flow: { nodes, heroes, recent, updated, is_loading },
|
||||||
user,
|
user,
|
||||||
nodeGotoNode,
|
nodeGotoNode,
|
||||||
flowSetCellView,
|
flowSetCellView,
|
||||||
flowGetMore
|
flowGetMore,
|
||||||
}) => {
|
}) => {
|
||||||
const loadMore = useCallback(() => {
|
const loadMore = useCallback(() => {
|
||||||
const pos =
|
const pos = window.scrollY + window.innerHeight - document.body.scrollHeight;
|
||||||
window.scrollY + window.innerHeight - document.body.scrollHeight;
|
|
||||||
|
|
||||||
if (is_loading || pos < -600) return;
|
if (is_loading || pos < -600) return;
|
||||||
|
|
||||||
|
@ -41,27 +39,31 @@ const FlowLayoutUnconnected: FC<IProps> = ({
|
||||||
}, [flowGetMore, is_loading]);
|
}, [flowGetMore, is_loading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.addEventListener("scroll", loadMore);
|
window.addEventListener('scroll', loadMore);
|
||||||
|
|
||||||
return () => window.removeEventListener("scroll", loadMore);
|
return () => window.removeEventListener('scroll', loadMore);
|
||||||
}, [loadMore]);
|
}, [loadMore]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<div className={styles.hero}>
|
||||||
|
<FlowHero heroes={heroes} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.stamp}>
|
||||||
|
<FlowRecent recent={recent} updated={updated} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<FlowGrid
|
<FlowGrid
|
||||||
nodes={nodes}
|
nodes={nodes}
|
||||||
heroes={heroes}
|
|
||||||
recent={recent}
|
|
||||||
updated={updated}
|
|
||||||
onSelect={nodeGotoNode}
|
onSelect={nodeGotoNode}
|
||||||
user={user}
|
user={user}
|
||||||
onChangeCellView={flowSetCellView}
|
onChangeCellView={flowSetCellView}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const FlowLayout = connect(
|
const FlowLayout = connect(mapStateToProps, mapDispatchToProps)(FlowLayoutUnconnected);
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(FlowLayoutUnconnected);
|
|
||||||
|
|
||||||
export { FlowLayout, FlowLayoutUnconnected };
|
export { FlowLayout, FlowLayoutUnconnected };
|
||||||
|
|
|
@ -4,3 +4,102 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cols: $content_width / $cell;
|
||||||
|
$stamp_color: $content_bg;
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
grid-template-rows: 50vh $cell;
|
||||||
|
grid-auto-rows: $cell;
|
||||||
|
|
||||||
|
grid-auto-flow: row dense;
|
||||||
|
grid-column-gap: $gap;
|
||||||
|
grid-row-gap: $gap;
|
||||||
|
|
||||||
|
@include tablet {
|
||||||
|
padding: 0 $gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $cell * 6) {
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
grid-template-rows: 50vh 20vw;
|
||||||
|
grid-auto-rows: 20vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $cell * 5) {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
grid-template-rows: 40vh 25vw;
|
||||||
|
grid-auto-rows: 25vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $cell * 4) {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-template-rows: 40vh 33vw;
|
||||||
|
grid-auto-rows: 33vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $cell * 3) {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-template-rows: 40vh 50vw;
|
||||||
|
grid-auto-rows: 50vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $cell * 2) {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-template-rows: 40vh 50vw;
|
||||||
|
grid-auto-rows: 50vw;
|
||||||
|
grid-column-gap: $gap;
|
||||||
|
grid-row-gap: $gap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pad_last {
|
||||||
|
grid-column-end: $cols + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
grid-row-start: 1;
|
||||||
|
grid-row-end: span 1;
|
||||||
|
grid-column-start: 1;
|
||||||
|
grid-column-end: -1;
|
||||||
|
background: darken($content_bg, 2%);
|
||||||
|
border-radius: $radius;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font: $font_24_semibold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp {
|
||||||
|
@include outer_shadow();
|
||||||
|
|
||||||
|
grid-row-end: span 2;
|
||||||
|
grid-column: -2 / -1;
|
||||||
|
background: $stamp_color;
|
||||||
|
border-radius: $radius;
|
||||||
|
padding: $gap;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font: $font_24_semibold;
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: stretch;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 60px;
|
||||||
|
width: 100%;
|
||||||
|
background: linear-gradient(transparentize($stamp_color, 1), $stamp_color 90%);
|
||||||
|
pointer-events: none;
|
||||||
|
touch-action: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue