import { ScrollListAction, ScrollListScrollAction, ScrollListUpdateAction, ScrollListJumpAction, SCROLL_LIST_SCROLL, SCROLL_LIST_UPDATE, SCROLL_LIST_JUMP, } from './actions' export interface ScrollListsState { [key: string]: ScrollListState } export interface ScrollListState { scroll: ScrollListScrollState height: number childHeight: number childrenVisible: number jumped: number | false } export interface ScrollListScrollState { scrollTop: number idx: number skip: number } export interface ScrollListItem { [id: string]: any } export const initialScrollListState: ScrollListsState = {} export const scrollListReducer = (state = initialScrollListState, action: ScrollListAction): ScrollListsState => { switch (action.type) { case SCROLL_LIST_SCROLL: { return scrollListScroll(state, action) } case SCROLL_LIST_UPDATE: { return scrollListUpdate(state, action) } case SCROLL_LIST_JUMP: { return scrollListJump(state, action) } default: { return state } } } const updateScrollList = (state: ScrollListsState, id: string, fn: (a: ScrollListState) => Partial) => ({ ...state, [id]: { ...state[id], ...fn(state[id]), }, }) const scrollListScroll = (state: ScrollListsState, action: ScrollListScrollAction) => updateScrollList(state, action.id, (scrollList: ScrollListState) => ({ scroll: action.scroll, })) const scrollListUpdate = (state: ScrollListsState, action: ScrollListUpdateAction) => updateScrollList(state, action.id, () => action.scrollList) const scrollListJump = (state: ScrollListsState, action: ScrollListJumpAction) => updateScrollList(state, action.id, (scrollList: ScrollListState) => ({ scroll: { idx: action.idx, scrollTop: action.idx > 0 ? scrollList.childHeight : 0, skip: Math.max(action.idx - 1, 0), }, jumped: action.idx, }))