import { RunnerPartialObject } from 'utils/variableHeight/types' import { buildPushTree, DataNode, Device, } from 'utils/variableHeight/buildPushTree' const GENERATE_PUSH_TREE = Symbol('GENERATE_PUSH_TREE') export interface PushTreePayload { objects: RunnerPartialObject[] dataMap: Record screenId: string device: Device } export interface PushTreeAction { type: Symbol payload: PushTreePayload } export type DataMap = Record export interface PushTreeState { screenPushTrees: Record device?: Device } const INITIAL_STATE: PushTreeState = { device: undefined, screenPushTrees: {}, } const reducer = ( // eslint-disable-next-line @typescript-eslint/default-param-last state: PushTreeState = INITIAL_STATE, action: PushTreeAction ) => { switch (action.type) { case GENERATE_PUSH_TREE: { const { screenId, objects, dataMap, device } = action.payload const newDataMap = buildPushTree(objects, dataMap, device) return { device, screenPushTrees: { ...state.screenPushTrees, [screenId]: newDataMap, }, } } } return state } export default reducer // actions export const generatePushTree = (payload: PushTreePayload): PushTreeAction => ({ type: GENERATE_PUSH_TREE, payload, }) // selectors export const getScreenPushTree = ( state: { pushTreeMap: PushTreeState }, screenId: string ): Record => state.pushTreeMap.screenPushTrees[screenId] || {} export const getNode = ( state: { pushTreeMap: PushTreeState }, screenId: string, nodeId: string ): DataNode => { const screen = getScreenPushTree(state, screenId) return screen?.[nodeId] } export const getNodeY = ( state: { pushTreeMap: PushTreeState }, componentId: string, id: string ): number => { const node = getNode(state, componentId, id) if (!node?.pushNode) { // console.warn('getNodeY - Could not getNode for', id, 'at screen', id) return 0 } return node.pushNode.originalY + node.pushNode.yOffset } export type RootPushTreeState = { pushTreeMap: PushTreeState } export const getNodeHeight = ( state: RootPushTreeState, componentId: string, id: string ): number => { const node = getNode(state, componentId, id) if (!node) { // console.warn('getNodeHeight - Could not getNode for', id, 'at screen', id) return 0 } return node.height }