import { SHUFFLE_CATALOG, setMagnetInstance, CLOSE_DETAIL, REBUILD_LAYOUT, rebuildLayout, OPEN_DETAIL } from '../actions/ui'; import { UPDATE_CATALOG } from '../actions/catalog'; import Magnet from '../../lib/magnet/magnet'; const magnet_opts = { itemSelector: '.grid-item', initLayout: false, hiddenStyle: { opacity: 0 }, visibleStyle: { opacity: 1 } }; export const updateCatalogFlow = ({ dispatch }) => next => action => { next(action); if (action.type === UPDATE_CATALOG) { if (action.payload.length) { setImmediate(() => dispatch(rebuildLayout())); } } }; export const _rebuildLayout = store => next => action => { next(action); if (action.type === REBUILD_LAYOUT) { const elem = document.querySelector('.grid-container'); if (!elem || elem.children.length === 0) { setImmediate(() => { store.dispatch(rebuildLayout()); }); return; } const magnetInstance = new Magnet(elem, { ...magnet_opts, stagger: 50 }); magnetInstance.arrange(); store.dispatch(setMagnetInstance(magnetInstance)); } }; export const shuffleLayout = store => next => action => { next(action); if (action.type === SHUFFLE_CATALOG) { const state = store.getState(); const magnetInstance = state.ui.magnetInstance; magnetInstance.shuffle(); } }; export const openDetailFlow = store => next => action => { if (action.type === OPEN_DETAIL) { /** * @see https://css-tricks.com/prevent-page-scrolling-when-a-modal-is-open/#article-header-id-3 */ // When the modal is shown, we want a fixed body document.body.style.top = `-${window.scrollY}px`; document.body.style.position = 'fixed'; document.body.style.overflow = 'hidden'; } next(action); }; export const closeDetailFlow = store => next => action => { next(action); if (action.type === CLOSE_DETAIL) { const state = store.getState(); if (state.ui.magnetInstance) { setImmediate(() => state.ui.magnetInstance.layout()); } /** * @see https://css-tricks.com/prevent-page-scrolling-when-a-modal-is-open/#article-header-id-3 */ // When the modal is hidden, we want to remain at the top of the scroll position const scrollY = document.body.style.top; document.body.style.overflow = 'visible'; document.body.style.position = ''; document.body.style.top = ''; window.scrollTo(0, parseInt(scrollY || '0') * -1); } }; export const uiMdl = [ updateCatalogFlow, _rebuildLayout, shuffleLayout, openDetailFlow, closeDetailFlow ];