diff --git a/src/components/flow/FlowStamp/index.tsx b/src/components/flow/FlowStamp/index.tsx index cf8b3308..3f206c6f 100644 --- a/src/components/flow/FlowStamp/index.tsx +++ b/src/components/flow/FlowStamp/index.tsx @@ -10,6 +10,7 @@ import { Group } from '~/components/containers/Group'; import { Toggle } from '~/components/input/Toggle'; import classNames from 'classnames'; import { Superpower } from '~/components/boris/Superpower'; +import { experimentalFeatures } from '~/constants/features'; interface IProps { recent: IFlowState['recent']; @@ -94,14 +95,16 @@ const FlowStamp: FC = ({ )} - -
- - -
Жидкое течение
-
-
-
+ {experimentalFeatures.liquidFlow && ( + +
+ + +
Жидкое течение
+
+
+
+ )} ); }; diff --git a/src/components/main/Header/styles.module.scss b/src/components/main/Header/styles.module.scss index 6ccd8b22..ec3dd377 100644 --- a/src/components/main/Header/styles.module.scss +++ b/src/components/main/Header/styles.module.scss @@ -28,7 +28,6 @@ align-items: center; justify-content: flex-end; font-weight: 500; - // padding: $gap; box-sizing: border-box; flex: 0 1 $content_width; } diff --git a/src/constants/features.ts b/src/constants/features.ts new file mode 100644 index 00000000..1324e9c2 --- /dev/null +++ b/src/constants/features.ts @@ -0,0 +1,7 @@ +export enum ExperimentalFeatures { + LiquidFlow = 'liquidFlow', +} + +export const experimentalFeatures: Record = { + [ExperimentalFeatures.LiquidFlow]: false, +}; diff --git a/src/layouts/FlowLayout/index.tsx b/src/layouts/FlowLayout/index.tsx index 7e29c0cd..bede37cf 100644 --- a/src/layouts/FlowLayout/index.tsx +++ b/src/layouts/FlowLayout/index.tsx @@ -19,28 +19,17 @@ import { INode } from '~/redux/types'; import { selectLabUpdatesNodes } from '~/redux/lab/selectors'; import { usePersistedState } from '~/utils/hooks/usePersistedState'; import classNames from 'classnames'; - -enum Layout { - Fluid = 'fluid', - Default = 'default', -} +import { useFlowLayout } from '~/utils/hooks/flow/useFlowLayout'; +import { useFlowPagination } from '~/utils/hooks/flow/useFlowPagination'; const FlowLayout: FC = () => { - const { nodes, heroes, recent, updated, is_loading, search } = useShallowSelect(selectFlow); - const [layout, setLayout] = usePersistedState('flow_layout', Layout.Default); + const { nodes, heroes, recent, updated, isLoading, search } = useShallowSelect(selectFlow); + const { isFluid, toggleLayout } = useFlowLayout(); const labUpdates = useShallowSelect(selectLabUpdatesNodes); const user = useShallowSelect(selectUser); const dispatch = useDispatch(); - const onLoadMore = useCallback(() => { - (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]); + useFlowPagination({ isLoading }); const onLoadMoreSearch = useCallback(() => { if (search.is_loading_more) return; @@ -66,17 +55,6 @@ const FlowLayout: FC = () => { 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(() => { window.scrollTo(0, (window as any).flowScrollPos || 0); }, []); diff --git a/src/redux/flow/reducer.ts b/src/redux/flow/reducer.ts index 7ab73585..bbf7452a 100644 --- a/src/redux/flow/reducer.ts +++ b/src/redux/flow/reducer.ts @@ -3,7 +3,7 @@ import { INode, IError } from '../types'; import { FLOW_HANDLERS } from './handlers'; export type IFlowState = Readonly<{ - is_loading: boolean; + isLoading: boolean; nodes: INode[]; heroes: Partial[]; recent: Partial[]; @@ -30,7 +30,7 @@ const INITIAL_STATE: IFlowState = { is_loading: false, is_loading_more: false, }, - is_loading: false, + isLoading: false, error: '', }; diff --git a/src/redux/flow/sagas.ts b/src/redux/flow/sagas.ts index 168561b4..3226d5d2 100644 --- a/src/redux/flow/sagas.ts +++ b/src/redux/flow/sagas.ts @@ -16,8 +16,7 @@ import { Unwrap } from '../types'; import { selectFlow, selectFlowNodes } from './selectors'; import { getSearchResults, postCellView } from './api'; import { uniq } from 'ramda'; -import { labSeenNode, labSetUpdates } from '~/redux/lab/actions'; -import { selectLabUpdatesNodes } from '~/redux/lab/selectors'; +import { labSeenNode } from '~/redux/lab/actions'; function hideLoader() { const loader = document.getElementById('main_loader'); @@ -43,7 +42,7 @@ function* onGetFlow() { hideLoader(); } - yield put(flowSetFlow({ is_loading: true })); + yield put(flowSetFlow({ isLoading: true })); const { before = [], @@ -62,7 +61,7 @@ function* onGetFlow() { 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 (recent.length) yield put(flowSetRecent(recent)); @@ -86,7 +85,7 @@ function* onSetCellView({ id, flow }: ReturnType) { function* getMore() { try { - yield put(flowSetFlow({ is_loading: true })); + yield put(flowSetFlow({ isLoading: true })); const nodes: ReturnType = yield select(selectFlowNodes); const start = nodes && nodes[0] && nodes[0].created_at; @@ -109,7 +108,7 @@ function* getMore() { yield put( flowSetFlow({ - is_loading: false, + isLoading: false, nodes: result, ...(data.recent ? { recent: data.recent } : {}), ...(data.updated ? { updated: data.updated } : {}), diff --git a/src/utils/hooks/flow/useFlowLayout.ts b/src/utils/hooks/flow/useFlowLayout.ts new file mode 100644 index 00000000..edcab5e9 --- /dev/null +++ b/src/utils/hooks/flow/useFlowLayout.ts @@ -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 }; +}; diff --git a/src/utils/hooks/flow/useFlowPagination.ts b/src/utils/hooks/flow/useFlowPagination.ts new file mode 100644 index 00000000..255d9f55 --- /dev/null +++ b/src/utils/hooks/flow/useFlowPagination.ts @@ -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]); +};