mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 04:46:40 +07:00
moved flow hooks out of flow
This commit is contained in:
parent
cac97e87f0
commit
35ce593ed8
8 changed files with 72 additions and 44 deletions
|
@ -10,6 +10,7 @@ import { Group } from '~/components/containers/Group';
|
||||||
import { Toggle } from '~/components/input/Toggle';
|
import { Toggle } from '~/components/input/Toggle';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Superpower } from '~/components/boris/Superpower';
|
import { Superpower } from '~/components/boris/Superpower';
|
||||||
|
import { experimentalFeatures } from '~/constants/features';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
recent: IFlowState['recent'];
|
recent: IFlowState['recent'];
|
||||||
|
@ -94,6 +95,7 @@ const FlowStamp: FC<IProps> = ({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{experimentalFeatures.liquidFlow && (
|
||||||
<Superpower>
|
<Superpower>
|
||||||
<div className={styles.toggles}>
|
<div className={styles.toggles}>
|
||||||
<Group horizontal onClick={toggleLayout} className={styles.fluid_toggle}>
|
<Group horizontal onClick={toggleLayout} className={styles.fluid_toggle}>
|
||||||
|
@ -102,6 +104,7 @@ const FlowStamp: FC<IProps> = ({
|
||||||
</Group>
|
</Group>
|
||||||
</div>
|
</div>
|
||||||
</Superpower>
|
</Superpower>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
// padding: $gap;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex: 0 1 $content_width;
|
flex: 0 1 $content_width;
|
||||||
}
|
}
|
||||||
|
|
7
src/constants/features.ts
Normal file
7
src/constants/features.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export enum ExperimentalFeatures {
|
||||||
|
LiquidFlow = 'liquidFlow',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const experimentalFeatures: Record<ExperimentalFeatures, boolean> = {
|
||||||
|
[ExperimentalFeatures.LiquidFlow]: false,
|
||||||
|
};
|
|
@ -19,28 +19,17 @@ import { INode } from '~/redux/types';
|
||||||
import { selectLabUpdatesNodes } from '~/redux/lab/selectors';
|
import { selectLabUpdatesNodes } from '~/redux/lab/selectors';
|
||||||
import { usePersistedState } from '~/utils/hooks/usePersistedState';
|
import { usePersistedState } from '~/utils/hooks/usePersistedState';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { useFlowLayout } from '~/utils/hooks/flow/useFlowLayout';
|
||||||
enum Layout {
|
import { useFlowPagination } from '~/utils/hooks/flow/useFlowPagination';
|
||||||
Fluid = 'fluid',
|
|
||||||
Default = 'default',
|
|
||||||
}
|
|
||||||
|
|
||||||
const FlowLayout: FC = () => {
|
const FlowLayout: FC = () => {
|
||||||
const { nodes, heroes, recent, updated, is_loading, search } = useShallowSelect(selectFlow);
|
const { nodes, heroes, recent, updated, isLoading, search } = useShallowSelect(selectFlow);
|
||||||
const [layout, setLayout] = usePersistedState('flow_layout', Layout.Default);
|
const { isFluid, toggleLayout } = useFlowLayout();
|
||||||
const labUpdates = useShallowSelect(selectLabUpdatesNodes);
|
const labUpdates = useShallowSelect(selectLabUpdatesNodes);
|
||||||
const user = useShallowSelect(selectUser);
|
const user = useShallowSelect(selectUser);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const onLoadMore = useCallback(() => {
|
useFlowPagination({ isLoading });
|
||||||
(window as any).flowScrollPos = window.scrollY;
|
|
||||||
|
|
||||||
const pos = window.scrollY + window.innerHeight - document.body.scrollHeight;
|
|
||||||
|
|
||||||
if (is_loading || pos < -600) return;
|
|
||||||
|
|
||||||
dispatch(flowGetMore());
|
|
||||||
}, [dispatch, is_loading]);
|
|
||||||
|
|
||||||
const onLoadMoreSearch = useCallback(() => {
|
const onLoadMoreSearch = useCallback(() => {
|
||||||
if (search.is_loading_more) return;
|
if (search.is_loading_more) return;
|
||||||
|
@ -66,17 +55,6 @@ const FlowLayout: FC = () => {
|
||||||
labUpdates,
|
labUpdates,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const isFluid = layout === Layout.Fluid;
|
|
||||||
const toggleLayout = useCallback(() => {
|
|
||||||
setLayout(isFluid ? Layout.Default : Layout.Fluid);
|
|
||||||
}, [setLayout, isFluid]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
window.addEventListener('scroll', onLoadMore);
|
|
||||||
|
|
||||||
return () => window.removeEventListener('scroll', onLoadMore);
|
|
||||||
}, [onLoadMore]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.scrollTo(0, (window as any).flowScrollPos || 0);
|
window.scrollTo(0, (window as any).flowScrollPos || 0);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { INode, IError } from '../types';
|
||||||
import { FLOW_HANDLERS } from './handlers';
|
import { FLOW_HANDLERS } from './handlers';
|
||||||
|
|
||||||
export type IFlowState = Readonly<{
|
export type IFlowState = Readonly<{
|
||||||
is_loading: boolean;
|
isLoading: boolean;
|
||||||
nodes: INode[];
|
nodes: INode[];
|
||||||
heroes: Partial<INode>[];
|
heroes: Partial<INode>[];
|
||||||
recent: Partial<INode>[];
|
recent: Partial<INode>[];
|
||||||
|
@ -30,7 +30,7 @@ const INITIAL_STATE: IFlowState = {
|
||||||
is_loading: false,
|
is_loading: false,
|
||||||
is_loading_more: false,
|
is_loading_more: false,
|
||||||
},
|
},
|
||||||
is_loading: false,
|
isLoading: false,
|
||||||
error: '',
|
error: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,7 @@ import { Unwrap } from '../types';
|
||||||
import { selectFlow, selectFlowNodes } from './selectors';
|
import { selectFlow, selectFlowNodes } from './selectors';
|
||||||
import { getSearchResults, postCellView } from './api';
|
import { getSearchResults, postCellView } from './api';
|
||||||
import { uniq } from 'ramda';
|
import { uniq } from 'ramda';
|
||||||
import { labSeenNode, labSetUpdates } from '~/redux/lab/actions';
|
import { labSeenNode } from '~/redux/lab/actions';
|
||||||
import { selectLabUpdatesNodes } from '~/redux/lab/selectors';
|
|
||||||
|
|
||||||
function hideLoader() {
|
function hideLoader() {
|
||||||
const loader = document.getElementById('main_loader');
|
const loader = document.getElementById('main_loader');
|
||||||
|
@ -43,7 +42,7 @@ function* onGetFlow() {
|
||||||
hideLoader();
|
hideLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(flowSetFlow({ is_loading: true }));
|
yield put(flowSetFlow({ isLoading: true }));
|
||||||
|
|
||||||
const {
|
const {
|
||||||
before = [],
|
before = [],
|
||||||
|
@ -62,7 +61,7 @@ function* onGetFlow() {
|
||||||
|
|
||||||
const result = uniq([...(before || []), ...(after || [])]);
|
const result = uniq([...(before || []), ...(after || [])]);
|
||||||
|
|
||||||
yield put(flowSetFlow({ is_loading: false, nodes: result }));
|
yield put(flowSetFlow({ isLoading: false, nodes: result }));
|
||||||
|
|
||||||
if (heroes.length) yield put(flowSetHeroes(heroes));
|
if (heroes.length) yield put(flowSetHeroes(heroes));
|
||||||
if (recent.length) yield put(flowSetRecent(recent));
|
if (recent.length) yield put(flowSetRecent(recent));
|
||||||
|
@ -86,7 +85,7 @@ function* onSetCellView({ id, flow }: ReturnType<typeof flowSetCellView>) {
|
||||||
|
|
||||||
function* getMore() {
|
function* getMore() {
|
||||||
try {
|
try {
|
||||||
yield put(flowSetFlow({ is_loading: true }));
|
yield put(flowSetFlow({ isLoading: true }));
|
||||||
const nodes: ReturnType<typeof selectFlowNodes> = yield select(selectFlowNodes);
|
const nodes: ReturnType<typeof selectFlowNodes> = yield select(selectFlowNodes);
|
||||||
|
|
||||||
const start = nodes && nodes[0] && nodes[0].created_at;
|
const start = nodes && nodes[0] && nodes[0].created_at;
|
||||||
|
@ -109,7 +108,7 @@ function* getMore() {
|
||||||
|
|
||||||
yield put(
|
yield put(
|
||||||
flowSetFlow({
|
flowSetFlow({
|
||||||
is_loading: false,
|
isLoading: false,
|
||||||
nodes: result,
|
nodes: result,
|
||||||
...(data.recent ? { recent: data.recent } : {}),
|
...(data.recent ? { recent: data.recent } : {}),
|
||||||
...(data.updated ? { updated: data.updated } : {}),
|
...(data.updated ? { updated: data.updated } : {}),
|
||||||
|
|
19
src/utils/hooks/flow/useFlowLayout.ts
Normal file
19
src/utils/hooks/flow/useFlowLayout.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { usePersistedState } from '~/utils/hooks/usePersistedState';
|
||||||
|
import { experimentalFeatures } from '~/constants/features';
|
||||||
|
|
||||||
|
enum Layout {
|
||||||
|
Fluid = 'fluid',
|
||||||
|
Default = 'default',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useFlowLayout = () => {
|
||||||
|
const [layout, setLayout] = usePersistedState('flow_layout', Layout.Default);
|
||||||
|
const isFluid = layout === Layout.Fluid && experimentalFeatures.liquidFlow;
|
||||||
|
|
||||||
|
const toggleLayout = useCallback(() => {
|
||||||
|
setLayout(isFluid ? Layout.Default : Layout.Fluid);
|
||||||
|
}, [setLayout, isFluid]);
|
||||||
|
|
||||||
|
return { isFluid, toggleLayout };
|
||||||
|
};
|
23
src/utils/hooks/flow/useFlowPagination.ts
Normal file
23
src/utils/hooks/flow/useFlowPagination.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { useCallback, useEffect } from 'react';
|
||||||
|
import { flowGetMore } from '~/redux/flow/actions';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
|
export const useFlowPagination = ({ isLoading }) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const onLoadMore = useCallback(() => {
|
||||||
|
(window as any).flowScrollPos = window.scrollY;
|
||||||
|
|
||||||
|
const pos = window.scrollY + window.innerHeight - document.body.scrollHeight;
|
||||||
|
|
||||||
|
if (isLoading || pos < -600) return;
|
||||||
|
|
||||||
|
dispatch(flowGetMore());
|
||||||
|
}, [dispatch, isLoading]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener('scroll', onLoadMore);
|
||||||
|
|
||||||
|
return () => window.removeEventListener('scroll', onLoadMore);
|
||||||
|
}, [onLoadMore]);
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue