alpinesmuseum-public/assets/js/redux/middleware/ui.js
2022-09-23 07:38:37 +05:30

99 lines
2.4 KiB
JavaScript

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
];