import { Record as ImmutableRecord, Stack } from "immutable"; import { type Reducer } from "@reduxjs/toolkit"; import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from "../actions/compose"; import { type ModalType } from "../actions/modal"; import { openModal, closeModal } from "../actions/modal"; import { TIMELINE_DELETE } from "../actions/timelines"; export type ModalProps = Record; interface Modal { modalType: ModalType, modalProps: ModalProps, } const Modal = ImmutableRecord({ modalType: "ACTIONS", modalProps: ImmutableRecord({})(), }); interface ModalState { ignoreFocus: boolean, stack: Stack>, } const initialState = ImmutableRecord({ ignoreFocus: false, stack: Stack(), })(); type State = typeof initialState; interface PopModalOption { modalType: ModalType | undefined, ignoreFocus: boolean, } const popModal = ( state: State, { modalType, ignoreFocus }: PopModalOption, ): State => { if ( modalType === undefined || modalType === state.get("stack").get(0)?.get("modalType") ) { return state .set("ignoreFocus", ignoreFocus) .update("stack", (stack) => stack.shift()); } else { return state; } }; const pushModal = ( state: State, modalType: ModalType, modalProps: ModalProps, ): State => { return state.withMutations((record) => { record.set("ignoreFocus", false); record.update("stack", (stack) => stack.unshift(Modal({ modalType, modalProps })), ); }); }; export const modalReducer: Reducer = (state = initialState, action) => { if (openModal.match(action)) { return pushModal( state, action.payload.modalType, action.payload.modalProps, ); } else if (closeModal.match(action)) { return popModal(state, action.payload); } else if (action.type === COMPOSE_UPLOAD_CHANGE_SUCCESS) { return popModal(state, { modalType: "FOCAL_POINT", ignoreFocus: false }); } else if (action.type === TIMELINE_DELETE) { return state.update("stack", (stack) => stack.filterNot( (modal) => modal.get("modalProps").statusId === action.id, ), ); } else { return state; } };