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

added lab pagination

This commit is contained in:
Fedor Katurov 2021-10-05 12:44:28 +07:00
parent ae93ff065d
commit c986bc434b
8 changed files with 79 additions and 21 deletions

View file

@ -55,10 +55,6 @@ const FlowLayout: FC = () => {
labUpdates, labUpdates,
]); ]);
useEffect(() => {
window.scrollTo(0, (window as any).flowScrollPos || 0);
}, []);
return ( return (
<div className={classNames(styles.container, { [styles.fluid]: isFluid })}> <div className={classNames(styles.container, { [styles.fluid]: isFluid })}>
<div className={styles.grid}> <div className={styles.grid}>

View file

@ -15,6 +15,7 @@ import { Superpower } from '~/components/boris/Superpower';
import { Toggle } from '~/components/input/Toggle'; import { Toggle } from '~/components/input/Toggle';
import { usePersistedState } from '~/utils/hooks/usePersistedState'; import { usePersistedState } from '~/utils/hooks/usePersistedState';
import classNames from 'classnames'; import classNames from 'classnames';
import { useLabPagination } from '~/utils/hooks/lab/useLabPagination';
interface IProps {} interface IProps {}
@ -22,6 +23,8 @@ const LabLayout: FC<IProps> = () => {
const { is_loading } = useShallowSelect(selectLabList); const { is_loading } = useShallowSelect(selectLabList);
const dispatch = useDispatch(); const dispatch = useDispatch();
useLabPagination({ isLoading: is_loading });
useEffect(() => { useEffect(() => {
dispatch(labGetList()); dispatch(labGetList());
dispatch(labGetStats()); dispatch(labGetStats());

View file

@ -34,3 +34,7 @@ export const labSeenNode = (nodeId: INode['id']) => ({
type: LAB_ACTIONS.SEEN_NODE, type: LAB_ACTIONS.SEEN_NODE,
nodeId, nodeId,
}); });
export const labGetMore = () => ({
type: LAB_ACTIONS.GET_MORE,
});

View file

@ -10,4 +10,5 @@ export const LAB_ACTIONS = {
SET_UPDATES: `${prefix}SET_UPDATES`, SET_UPDATES: `${prefix}SET_UPDATES`,
GET_UPDATES: `${prefix}GET_UPDATES`, GET_UPDATES: `${prefix}GET_UPDATES`,
SEEN_NODE: `${prefix}SET_UPDATE_SEEN`, SEEN_NODE: `${prefix}SET_UPDATE_SEEN`,
GET_MORE: `${prefix}GET_MORE`,
}; };

View file

@ -9,7 +9,7 @@ import {
import { LAB_ACTIONS } from '~/redux/lab/constants'; import { LAB_ACTIONS } from '~/redux/lab/constants';
import { Unwrap } from '~/redux/types'; import { Unwrap } from '~/redux/types';
import { getLabNodes, getLabStats, getLabUpdates } from '~/redux/lab/api'; import { getLabNodes, getLabStats, getLabUpdates } from '~/redux/lab/api';
import { selectLabUpdatesNodes } from '~/redux/lab/selectors'; import { selectLabList, selectLabUpdatesNodes } from '~/redux/lab/selectors';
function* getList({ after = '' }: ReturnType<typeof labGetList>) { function* getList({ after = '' }: ReturnType<typeof labGetList>) {
try { try {
@ -53,10 +53,39 @@ function* seenNode({ nodeId }: ReturnType<typeof labSeenNode>) {
yield put(labSetUpdates({ nodes: newNodes })); yield put(labSetUpdates({ nodes: newNodes }));
} }
function* getMore() {
try {
yield put(labSetList({ is_loading: true }));
const list: ReturnType<typeof selectLabList> = yield select(selectLabList);
if (list.nodes.length === list.count) {
return;
}
const last = list.nodes[list.nodes.length];
if (!last) {
return;
}
const after = last.node.created_at;
const { nodes, count }: Unwrap<typeof getLabNodes> = yield call(getLabNodes, { after });
const newNodes = [...list.nodes, ...nodes];
yield put(labSetList({ nodes: newNodes, count }));
} catch (error) {
yield put(labSetList({ error: error.message }));
} finally {
yield put(labSetList({ is_loading: false }));
}
}
export default function* labSaga() { export default function* labSaga() {
yield takeLeading(LAB_ACTIONS.GET_LIST, getList); yield takeLeading(LAB_ACTIONS.GET_LIST, getList);
yield takeLeading(LAB_ACTIONS.GET_STATS, getStats); yield takeLeading(LAB_ACTIONS.GET_STATS, getStats);
yield takeLeading(LAB_ACTIONS.GET_UPDATES, getUpdates); yield takeLeading(LAB_ACTIONS.GET_UPDATES, getUpdates);
yield takeLeading(LAB_ACTIONS.SEEN_NODE, seenNode); yield takeLeading(LAB_ACTIONS.SEEN_NODE, seenNode);
yield takeLeading(LAB_ACTIONS.GET_MORE, getMore);
} }

View file

@ -1,23 +1,10 @@
import { useCallback, useEffect } from 'react'; import { useCallback, useEffect } from 'react';
import { flowGetMore } from '~/redux/flow/actions'; import { flowGetMore } from '~/redux/flow/actions';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { useInfiniteLoader } from '~/utils/hooks/useInfiniteLoader';
export const useFlowPagination = ({ isLoading }) => { export const useFlowPagination = ({ isLoading }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const loadMore = useCallback(() => dispatch(flowGetMore()), []);
const onLoadMore = useCallback(() => { useInfiniteLoader(loadMore, isLoading);
(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]);
}; };

View file

@ -0,0 +1,21 @@
import { useDispatch } from 'react-redux';
import { useCallback } from 'react';
import { useInfiniteLoader } from '~/utils/hooks/useInfiniteLoader';
import { labGetMore } from '~/redux/lab/actions';
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import { selectLabList } from '~/redux/lab/selectors';
export const useLabPagination = ({ isLoading }) => {
const { nodes, count } = useShallowSelect(selectLabList);
const dispatch = useDispatch();
const loadMore = useCallback(() => {
if (nodes.length >= count) {
return;
}
dispatch(labGetMore());
}, [nodes, count]);
useInfiniteLoader(loadMore, isLoading);
};

View file

@ -0,0 +1,17 @@
import { useCallback, useEffect } from 'react';
export const useInfiniteLoader = (loader: () => void, isLoading?: boolean) => {
const onLoadMore = useCallback(() => {
const pos = window.scrollY + window.innerHeight - document.body.scrollHeight;
if (isLoading || pos < -600) return;
loader();
}, [loader, isLoading]);
useEffect(() => {
window.addEventListener('scroll', onLoadMore);
return () => window.removeEventListener('scroll', onLoadMore);
}, [onLoadMore]);
};